Skip to content

Instantly share code, notes, and snippets.

@mrtank
Created August 17, 2018 14:50
Show Gist options
  • Save mrtank/f923fb6ec0d865219d37cc178e0f9fc2 to your computer and use it in GitHub Desktop.
Save mrtank/f923fb6ec0d865219d37cc178e0f9fc2 to your computer and use it in GitHub Desktop.
Matrix
// Learn more about F# at http://fsharp.org
// See the 'F# Tutorial' project for more help.
open System
open System.Runtime.InteropServices
open System.Text
type HANDLE = nativeint
[<StructLayout(LayoutKind.Sequential)>]
type COORD =
struct
val X: Int16
val Y: Int16
new(x: Int16, y: Int16) = { X = x; Y = y }
end
[<DllImport("kernel32", SetLastError=true, CharSet=CharSet.Auto)>]
extern bool WriteConsoleOutputCharacter(HANDLE hConsoleOutput, [<MarshalAs(UnmanagedType.LPWStr)>]StringBuilder lpCharacter, UInt32 nLength, COORD dwWriteCoord, UInt32& lpNumberOfCharsWritten)
[<DllImport("Kernel32")>]
extern void* GetStdHandle(int nStdHandle)
let rand = Random()
let chooseCharacter() =
[437, 447; 568, 591; 953, 1023]
|> (fun x -> List.item (rand.Next(x.Length)) x)
||> (fun x y -> rand.Next(x, y))
|> char
[<EntryPoint>]
let main _ =
Console.ForegroundColor <- ConsoleColor.DarkGreen
Console.OutputEncoding <- Text.Encoding.UTF8
let render() =
let putChar (x: int) (y: int) char =
let mutable lpNumberOfCharsWritten = 1u
let windowHandle =
GetStdHandle(-11)
WriteConsoleOutputCharacter(windowHandle, StringBuilder(char |> string), 1u, COORD(Convert.ToInt16(x), Convert.ToInt16(y)), &lpNumberOfCharsWritten) |> ignore
let error = Marshal.GetLastWin32Error()
if error <> 0 then
printf "Check out error code %i on that page: https://docs.microsoft.com/en-us/windows/desktop/Debug/system-error-codes--0-499- " error
let rec printColumn x y waitTime stepLeft =
async {
if stepLeft > 0 then
do! Async.Sleep waitTime
putChar x y (chooseCharacter())
if y < Console.WindowHeight then
do! printColumn x (y + 1) waitTime (stepLeft - 1)
}
let rec taskForWaitingSeed seed =
async {
do! Async.Sleep (seed * 300)
let y = rand.Next(Console.WindowHeight + 1)
let x = rand.Next(Console.WindowWidth)
let waitTimeBetweenColumnIteration =
((rand.Next(4) + 1) * 20 + 100)
let columnLength =
rand.Next(9) + 2
do! Async.StartChild (printColumn x y waitTimeBetweenColumnIteration columnLength) |> Async.Ignore
let newSeed =
rand.Next(5)
do! taskForWaitingSeed newSeed
}
Async.StartChild (taskForWaitingSeed 0) |> Async.Ignore
render() |> Async.RunSynchronously
Console.ReadKey() |> ignore
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment