RosettaCodeData/Task/Flipping-bits-game/FutureBasic/flipping-bits-game.basic

100 lines
2.7 KiB
Plaintext

uint16 board( 9 ), goal( 9 )
int size, count, mask
colorref hue( 1 )
CFStringRef key
bool win
local fn show
int x = 20, y = 20, row, col, v, t = size * 20 + 63
text @"Courier", 17, fn ColorGray, fn colorClear
cls
printf@"\n GOAL"
print @( size * 2 + 8, 1 )"BOARD"
for row = 0 to size -1
y = row * 20 + 40
for col = 0 to size - 1
v = ( goal( row ) & bit( col ) ) > 0
x = col * 20 + 20
rect fill ( x, y, 19, 19 ), hue( v )
print %( x + 5, y - 2 ) v
x += t
v = ( board( row ) & bit( col ) ) > 0
rect fill ( x, y, 19, 19 ), hue( v )
print %( x + 5, y - 2 ) v
next
print %( x + 25, y - 2 ) mid( key, size + row, 1 )
next
//print %( t + 15, y + 17 ) left( @" A B C D E F G H I J", size * 2 ) //Alternate
print %( t + 15, y + 17 ) left( @" Q W E R T Y U I O P", size * 2 )
print %( size * 20 + 26, size * 10 + 20 )@"MOVES"
print %( t - 18, size * 10 + 40 )count
end fn
local fn match as bool
for int r = 0 to size -1
if board( r ) <> goal( r ) then return no
next
end fn = yes
local fn move( k as int )
select k
case >= size : board( k - size) ^^= mask //row
case >= 0 //column
for int r = 0 to size -1
board( r ) ^^= bit( k )
next
case else : exit fn
end select
DialogEventSetBool(YES) // we handled the event
count ++
fn show
end fn
local fn newGame
int r
for r = 0 to size -1
board( r ) = rnd( mask ) -1
next
fn memmove( @goal( 0 ), @board( 0 ), 20 )
do
for r = 0 to size
fn move( rnd( size * 2 ) -1)
next
until !fn match
count = 0
fn show
end fn
local fn init( sz as int )
if sz < 3 | sz > 10 then stop "Size param must be 3-10" : end
size = sz
mask = bit( size ) - 1
hue( 0 ) = fn colorYellow
hue( 1 ) = fn colorcyan//Green
subclass window 1, @"Flipping bits puzzle", ( 0, 0, sz * 40 + 123, sz * 20 + 80 )¬
, NSWindowStyleMaskTitled + NSWindowStyleMaskClosable
//key = fn StringWithFormat( @"Q%@%@", left( @"ABCDEFGHIJ", sz ), left( @"1234567890", sz ) ) //Alternate
key = fn StringWithFormat( @"%@%@", LEFT( @"QWERTYUIOP", sz ), left( @"1234567890", sz ) )
fn newGame
end fn
local fn doDialog( evt as long )
select ( evt )
case _windowKeyDown
if win then win = no : fn newGame : exit fn
fn move( instr( 0, key, fn EventCharacters, NSCaseInsensitiveSearch ) )
if fn match
text ,,_zRed
print @(size*2 + 1, 0)"SOLVED!"
print %(20,size*20+50)"Any key for new game."
win = yes : beep
end if
case _windowWillClose : end
end select
end fn
on dialog fn DoDialog
fn init( 3 )
fn newGame
handleevents