-- | This module contains functions that get values from a list.
--   These functions are used to get values from randomized tables for random
--   generation purposes
module RealDice.Manipulate.GetValueFromRNGTable
  ( getBoolByIndex,
    getIntByIndex,
  )
where

-- | Gets an integer value from a list by index, looping back to the beginning
--   if the index is out of bounds

-- | This is used to get an element from a randomized table of integers

-- | ==== __Examples__
--   >>> getIntByIndex 2 [1, 0, 4, 3, 2]
--   4
--   >>> getIntByIndex 5 [1, 0, 4, 3, 2]
--   1
--   >>> getIntByIndex (-1337) [1, 0, 4, 3, 2]
--   3
getIntByIndex :: Int -> [Int] -> Int
getIntByIndex :: Int -> [Int] -> Int
getIntByIndex Int
index [Int]
l = [Int]
l [Int] -> Int -> Int
forall a. HasCallStack => [a] -> Int -> a
!! (Int
index Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
l)

-- | Gets a boolean value from a list by index, looping back to the beginning
--   if the index is out of bounds

-- | After looping over the list once, we flip the values of the elements
--     so that we can use an odd list length while still having an even
--     distribution of "True" and "False" values

-- | This is used to get an element from a randomized table of booleans

-- | ==== __Examples__
--   >>> getBoolByIndex 2 [True, False, False, True, True]
--   False
--   >>> getBoolByIndex 5 [True, False, False, True, True]
--   False
--   >>> getBoolByIndex 6 [True, False, False, True, True]
--   True
--   >>> getBoolByIndex (-1337) [True, False, True, False, True]
--   False
getBoolByIndex :: Int -> [Bool] -> Bool
getBoolByIndex :: Int -> [Bool] -> Bool
getBoolByIndex Int
index [Bool]
l =
  if (Int
index Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` ([Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
l Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
l
    then [Bool]
l [Bool] -> Int -> Bool
forall a. HasCallStack => [a] -> Int -> a
!! (Int
index Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` ([Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
l Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2))
    else Bool -> Bool
not ([Bool]
l [Bool] -> Int -> Bool
forall a. HasCallStack => [a] -> Int -> a
!! ((Int
index Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` ([Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
l Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Bool] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Bool]
l))