100 lines
2.7 KiB
Plaintext
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
|