From bee0febb5d98f0993a7a3bd175046f4fbf9c8eec Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 15 Dec 2024 19:31:47 +0530 Subject: Generate random key sequences with lcg --- src/Chelleport.hs | 6 ++++-- src/Chelleport/KeySequence.hs | 38 +++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Chelleport.hs b/src/Chelleport.hs index 82188b9..cb0ed84 100644 --- a/src/Chelleport.hs +++ b/src/Chelleport.hs @@ -7,6 +7,8 @@ import Chelleport.KeySequence (eventToKeycode, findMatchPosition, generateGrid, import Chelleport.Types import Chelleport.Utils (intToCInt) import qualified Chelleport.View +import Data.List ((\\)) +import Data.Maybe (fromMaybe) import qualified SDL open :: IO () @@ -14,12 +16,12 @@ open = setupAppShell initialState update eventToAction Chelleport.View.render initialState :: DrawContext -> IO State initialState _ctx = do - let cells = generateGrid (rows, columns) hintKeys + let cells = fromMaybe (pure undefined) $ generateGrid 0 (rows, columns) hintKeys pure $ State {stateGrid = cells, stateKeySequence = []} where rows = 12 columns = 12 - hintKeys = "ABCDEFGHIJKLMNOPRSTUVWXYZ1234567890" + hintKeys = ['A' .. 'Z'] \\ "Q" update :: Update State AppAction update state _ctx (FilterSequence key) = diff --git a/src/Chelleport/KeySequence.hs b/src/Chelleport/KeySequence.hs index f112b57..9f7b5db 100644 --- a/src/Chelleport/KeySequence.hs +++ b/src/Chelleport/KeySequence.hs @@ -25,22 +25,30 @@ findMatchPosition keySequence = findWithIndex searchRows 0 isValidKey :: SDL.Keycode -> Bool isValidKey = (`Map.member` keycodeMapping) -generateKeyCells :: (Int, Int) -> KeySequence -> KeyGrid -generateKeyCells (rows, columns) hintKeys = - (\row -> getCellSeq row <$> [1 .. columns]) <$> [1 .. rows] +-- Linear Congruential Generator +lcg :: Int -> Int +lcg seed = (a * seed + c) `mod` fromIntegral m where - getCellSeq row col = [getPrefixHoriz row col, getPrefixVert row col, getKey row col] - getKey row col = hintKeys !! index - where - index = (secRow * (columns `div` 2) + secCol) `mod` length hintKeys - secCol = (col - 1) `mod` (columns `div` 2) - secRow = (row - 1) `mod` (rows `div` 2) - getPrefixHoriz _row col - | col <= (columns `div` 2) = 'H' - | otherwise = 'L' - getPrefixVert row _col - | row <= (rows `div` 2) = 'K' - | otherwise = 'J' + a = 1664525 + c = 1013904223 + m = (2 :: Integer) ^ (32 :: Integer) + +getIndexRounded :: Int -> [a] -> a +getIndexRounded i ls = ls !! (i `mod` length ls) + +generateGrid :: Int -> (Int, Int) -> KeySequence -> Maybe KeyGrid +generateGrid seed (rows, columns) hintKeys + | rows * columns > length hintKeys * length hintKeys = Nothing + | otherwise = Just $ (\row -> getKeySeq row <$> [0 .. columns - 1]) <$> [0 .. rows - 1] + where + allKeySeq = take numPairs . uniq $ generatePairs + numPairs = rows * columns + getKeySeq row col = allKeySeq !! (row * columns + col) + randomNumbers = iterate lcg seed + generatePairs = + [ [getIndexRounded i hintKeys, getIndexRounded j hintKeys] + | (i, j) <- zip randomNumbers (drop numPairs randomNumbers) + ] toKeyChar :: SDL.Keycode -> Maybe Char toKeyChar = (`Map.lookup` keycodeMapping) -- cgit v1.3.1