#!/usr/bin/env BQN # SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-FileCopyrightText: 2023 Rampoina ⟨ansi⟩←•Import "ansi.bqn" ⟨Game⟩←•Import "logic.bqn" opts←{ a←•args _optl_←{≠◶⟨𝔾,𝔽⊑⟩ (»a∊𝕩)/a} _opt_←{ 𝔽_optl_𝔾 ⋈𝕩} {𝕤 •Out "Usage: "∾•name∾" [OPTION]... -h,--help Displays a help message -l,--levels FILE Load levels from FILE. (default: a file called “levels”). -c,--chars string Characters to display for each game object, needs to have length 15. (default: ” λ$⊕⭍#/-|+<>^v”). -f,--fchars string Characters to represent each game object in the levels file, needs to have length 15. (default: ” @$o⭍#/-|+<>^v”). -s,--start N Start directly at level number N. (default: 1)." •Exit 0 }⍟∨´"-h"‿"--help"∊a chars ⇐ ⊢_optl_" λ$⊕⭍#/\-|+<>^v" "-c"‿"--chars" fchars⇐ ⊢_optl_" @$o⭍#/\-|+<>^v" "-f"‿"--fchars" levels⇐ ⊢_optl_"levels" "-l"‿"--levels" n⇐{1⌈•BQN⎊{𝕊: •Out "Invalid starting level number" ⋄ •Exit 1} 𝕩}_optl_ 1 "-s"‿"--start" } g←Game⎊{𝕊: •Out •CurrentError @ ⋄ •Exit 1} opts.n‿opts.levels‿opts.chars‿opts.fchars‿⟨ansi.defaultB,ansi.yellow,ansi.cyan,ansi.red⟩ ansi.InitTerm @ clear←"" {𝕤 # Loop until the user wins •Out clear∾ansi.cursor.origin clear↩"" •Out "Level: "∾•Repr 1+g.currentLevel •Out (g.Color g.pmachine)∾ansi.defaultB∾" Power the machines ("∾(g.Color g.machine)∾") by moving the mirrors ("∾(∾g.Color¨ g.mirrors)∾ansi.defaultB∾")" •Out "Controls: (hjkl or wasd) to move, u to undo, r to reset level, q to quit" g.Draw @ •Out "Moves: "∾•Repr ¯1+≠g.moves g.WinLevel @ ? •Out "Good job!, press any key to continue to the next level" key←•term.CharB @ clear↩ansi.clear.screen g.NextLevel @ {𝕤⋄ansi.RestoreTerm @⋄•Exit 0}⍟(key='q')@ ; key←•term.CharB @ {𝕤⋄g.Next ⊑("hjklaswd"=key)/∾˜⟨0‿¯1,1‿0,¯1‿0,0‿1⟩}⍟(⊑key∊"hjklaswd")@ {𝕤⋄clear↩""‿ansi.clear.screen⊑˜((1⊸+>○(≠•Repr)⊢)¯1+≠g.moves)⋄g.Undo @}⍟(key='u')@ {𝕤⋄ansi.RestoreTerm @⋄•Exit 0}⍟(key='q')@ {𝕤⋄clear↩ansi.clear.screen⋄g.Reset @}⍟(key='r')@ }•_While_{𝕤⋄g.Over @}@ •Out "Well played, you win!" ansi.RestoreTerm @