Flipping bits game: Difference between revisions

Added Forth entry.
m (→‎{{header|REXX}}: fixed a typo.)
imported>CyD
(Added Forth entry.)
 
(24 intermediate revisions by 13 users not shown)
Line 3:
 
;The game:
Given an N by  '''N×N'''   square array of zeroes or ones in an initial configuration,   and a target configuration of zeroes and ones.
 
configuration, and a target configuration of zeroes and ones
 
The task is to transform one to the other in as few moves as
The game is to transform one to the other in as few moves as possible by inverting whole numbered rows or whole lettered
columns at once,   (as one move).
 
In an inversion.   any  '''1'''  becomes  '''0''',   and any  '''0'''  becomes  '''1'''  for that whole row or column.
 
In an inversion any 1 becomes 0, and any 0 becomes 1 for that
whole row or column.
 
;Task:
Line 16:
# The game should create an original random target configuration and a starting configuration.
# Ensure that the starting position is ''never'' the target position.
# The target position must be guaranteed as reachable from the starting position.   (One possible way to do this is to generate the start position by legal flips from a random target position.   The flips will always be reversible back to the target from the given start position).
# The number of moves taken so far should be shown.
 
 
<br>
Show an example of a short game here, on this page, for a 3 by&nbsp; '''3&times;3''' &nbsp; array of bits.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V ascii_lowercase = ‘abcdefghij’
V digits = ‘0123456789’ // to get round ‘bug in MSVC 2017’[https://developercommunity.visualstudio.com/t/bug-with-operator-in-c/565417]
 
V n = 3
 
V board = [[0] * n] * n
 
F setbits(&board, count = 1)
L 0 .< count
board[random:(:n)][random:(:n)] (+)= 1
 
F fliprow(i)
L(j) 0 .< :n
:board[i - 1][j] (+)= 1
 
F flipcol(i)
L(&row) :board
row[i] (+)= 1
 
F shuffle(board, count = 1)
L 0 .< count
I random:(0 .< 2) != 0
fliprow(random:(:n) + 1)
E
flipcol(random:(:n))
 
F pr(board, comment = ‘’)
print(comment)
print(‘ ’(0 .< :n).map(i -> :ascii_lowercase[i]).join(‘ ’))
print(‘ ’enumerate(board, 1).map((j, line) -> ([‘#2’.format(j)] [+] line.map(i -> String(i))).join(‘ ’)).join("\n "))
 
F init(&board)
setbits(&board, count' random:(:n) + 1)
V target = copy(board)
L board == target
shuffle(board, count' 2 * :n)
V prompt = ‘ X, T, or 1-#. / #.-#. to flip: ’.format(:n, :ascii_lowercase[0], :ascii_lowercase[:n - 1])
R (target, prompt)
 
V (target, prompt) = init(&board)
pr(target, ‘Target configuration is:’)
print(‘’)
V turns = 0
L board != target
turns++
pr(board, turns‘:’)
V ans = input(prompt).trim(‘ ’)
I (ans.len == 1 & ans C ascii_lowercase & ascii_lowercase.index(ans) < n)
flipcol(ascii_lowercase.index(ans))
E I ans != ‘’ & all(ans.map(ch -> ch C :digits)) & Int(ans) C 1 .. n
fliprow(Int(ans))
E I ans == ‘T’
pr(target, ‘Target configuration is:’)
turns--
E I ans == ‘X’
L.break
E
print(" I don't understand '#.'... Try again. (X to exit or T to show target)\n".format(ans[0.<9]))
turns--
L.was_no_break
print("\nWell done!\nBye.")</syntaxhighlight>
 
{{out}}
<pre>
Target configuration is:
a b c
1 0 0 1
2 0 0 0
3 0 0 0
 
1:
a b c
1 1 1 0
2 0 0 0
3 1 1 1
X, T, or 1-3 / a-c to flip: 1
2:
a b c
1 0 0 1
2 0 0 0
3 1 1 1
X, T, or 1-3 / a-c to flip: 3
 
Well done!
Bye.
</pre>
 
=={{header|8080 Assembly}}==
 
This program runs under CP/M and takes the board size from the command line.
 
<syntaxhighlight lang="8080asm"> ;;; Flip the Bits game, CP/M version.
;;; CP/M zero page locations
cmdln: equ 80h
;;; CP/M system calls
getch: equ 1h
putch: equ 2h
rawio: equ 6h
puts: equ 9h
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Retrieve command line input. If it is not correct, end.
lxi d,usage ; Usage string
mvi c,puts ; Print that string when we need to
lxi h,cmdln ; Pointer to command line
mov a,m ; Get length
ana a ; Zero?
jc 5 ; Then print and stop
inx h ; Advance to first non-space element
inx h
mov a,m ; Get first character
sui '3' ; Minimum number
jc 5 ; If input was less than that, print and stop
adi 3 ; Add 3 back, giving the board size
cpi 9 ; Is it higher than 8 now?
jnc 5 ; Then print usage and stop
sta boardsz ; Store the board size
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Because there's no standard way in CP/M to get at any
;;; entropy (not even a clock), ask the user to supply some
;;; by pressing the keys on the keyboard.
lxi d,presskeys
call outs
mvi b,8 ; we want to do this 8 times, for 24 keys total
randouter: mvi c,3 ; there are 3 bytes of state for the RNG
lxi h,xabcdat+1
randinner: push h ; keep the pointer and counters
push b
waitkey: mvi c,rawio
mvi e,0FFh
call 5
ana a
jz waitkey
pop b ; restore the pointer and counters
pop h
xra m ; XOR key with data
mov m,a
inx h
dcr c ; Have we had 3 bytes yet?
jnz randinner
dcr b ; Have we done it 8 times yet?
jnz randouter
lxi d,welcome
call outs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Generate a random board
lxi h,board
lxi b,4001h ; B=81, C=1
genrand: call xabcrand
ana c
mov m,a
inx h
dcr b
jnz genrand
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Copy board into goal
lxi h,board
lxi d,goal
mvi b,64
copygoal: mov a,m
stax d
inx h
inx d
dcr b
jnz copygoal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Do a bunch of random flips on the board (5-20)
call xabcrand
ani 0Fh ; 0..15 flips
adi 5 ; 5..20 flips
sta sysflips
mov b,a ; Do that many flips
randflip: call xabcrand
call flip ; Unused bits in the random number are ignored
dcr b
jnz randflip
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the current state
gamestate: lxi d,smoves
call outs
lda usrflips
call outanum
lxi d,sgoal
call outs
lda sysflips
call outanum
lxi d,newline
call outs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the current board and the goal
;;; Print the header first
lxi d,sboardhdr
call outs
lda boardsz
lxi d,2041h ; E=letter (A), D=space
add e ; Last letter
mov b,a ; B = last letter
mvi l,2 ; Print two headers
header: mvi e,'A'
mov a,d
call outaspace
headerpart: mov a,e
cmp b
jc headerltr
mov a,d ; Print spaces for invalid positions
headerltr: call outaspace
mov a,e
inr a
mov e,a
cpi 'A'+8
jc headerpart
mvi a,9
call outa
dcr l ; Print two headers (for two boards)
jnz header
lxi d,newline
call outs
;;; Then print each line of the board
mvi c,0 ; Start with line 0
printline: lxi h,board ; Get position on board
mvi d,2 ; Run twice - print board and goal
prbrdline: mvi a,'1' ; Print line number
add c
call outaspace
push d
mov a,c ; Line offset in board
rlc
rlc
rlc
mov e,a
mvi d,0
dad d ; Add line offset
pop d ; Restore board counter
mvi b,0 ; Start with column 0
printcol: lda boardsz ; Valid position?
dcr a
cmp b
jnc printbit
mvi a,' ' ; No - print space
jmp printpos
printbit: mov a,m ; Yes - print 0 or 1
adi '0'
printpos: call outaspace
inx h ; Next board pos
inr b
mov a,b ; Done yet?
cpi 8
jnz printcol ; If not, print next column
mvi a,9
call outa
lxi h,goal ; Print goal line next
dcr d
jnz prbrdline
mvi a,13 ; Print newline
call outa
mvi a,10
call outa
inr c ; Next line
lda boardsz ; Valid line?
dcr a
cmp c
jnc printline
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Prompt the user for a move
lxi d,prompt ; Print prompt
call outs
readinput: mvi c,getch ; Read character
call 5
ori 32 ; Make letters lowercase
cpi 'q' ; Quit?
rz
cpi '9'+1 ; 9 or lower? assume number
jc nummove
sui 'a' ; Otherwise, assume letter
jc invalid ; So <'a' is invalid input
call checkmove ; See if the move is valid
jc invalid ; If not, wrong input
ori 128 ; Set high bit for column flip
call flip ; Do the flip
jmp checkboard ; See if the game is won
nummove: sui '1' ; Board array is 0-based of course
jc invalid ; Not on board = invalid input
call checkmove ; See if the move is vali
jc invalid
call flip ; Do the move (high bit clear for row)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; See if the user has won
checkboard: lda boardsz
dcr a
mov b,a ; B = line
checkrow: lda boardsz
dcr a
mov c,a ; C = column
checkcol: mov a,b
rlc ; Line * 8
rlc
rlc
add c ; + column = offset
push b ; Store line/column
mvi h,0 ; Position offset
mov l,a
lxi d,board ; Get board
dad d
mov b,m ; B = board position
lxi d,64 ; Goal = board+64
dad d
mov a,m ; A = goal position
cmp b ; Are they the same?
pop b ; Restore line/column
jnz nowin ; If not, the user hasn't won
dcr c ; If so, try next column position
jp checkcol
dcr b ; If column done, try next row
jp checkrow
;;; If we get here, the user has won
lxi d,win
jmp outs
;;; The user hasn't won yet, get another move
nowin: lxi h,usrflips ; Increment the user flips
inr m
jmp gamestate ; Print new game state, get new move
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Invalid input: erase it, beep, and get another character
invalid: lxi d,nope
call outs
jmp readinput
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Check if the move in A is valid. Set carry if not.
checkmove: mov b,a
lda boardsz
dcr a
cmp b
mov a,b
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Flip row or column A & 7 (zero-indexed) on the board.
;;; Bit 7 set = column, else row.
flip: rlc ; Test bit 7 (and A*2)
jc flipcol
;;; Flip row
push b ; Keep registers
push h
ani 0Eh ; Get row number
rlc ; Calculate offset, A*4
rlc ; A*8
mvi b,0 ; BC = A
mov c,a
lxi h,board ; Get board pointer
dad b ; Add row offset
lxi b,0801h ; Max. 8 bits, and C=1 (to flip)
fliprowbit: mov a,m ; Get position
xra c ; Flip position
mov m,a ; Store position
inx h ; Increment pointer
dcr b ; Done yet?
jnz fliprowbit
pop h ; Restore registers
pop b
ret
;;; Flip column
flipcol: push b ; Keep registers
push d
push h
rrc ; Rotate A back
ani 7 ; Get column number
mvi d,0 ; Column offset
mov e,a
lxi h,board ; Get board pointer
dad d ; Add column offset
mvi e,8 ; Advance by 8 each time through the loop
lxi b,0801h ; Max. 8 bits, and C=1 (to flip)
flipcolbit: mov a,m ; Get position
xra c ; Flip position
mov m,a ; Store position
dad d ; Next row
dcr b ; Done yet?
jnz flipcolbit
pop h ; Restore registers
pop d
pop b
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; The "X ABC" 8-bit random number generator
xabcrand: push h
lxi h,xabcdat
inr m ; X++
mov a,m ; X,
inx h ;
xra m ; ^ C,
inx h ;
xra m ; ^ A,
mov m,a ; -> A
inx h
add m ; + B,
mov m,a ; -> B
rar ; >>1
dcx h
xra m ; ^ A,
dcx h
add m ; + C
mov m,a ; -> C
pop h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the string in DE. This saves one byte per call.
outs: mvi c,puts
jmp 5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the number in A in decimal, preserving registers
outanum: push psw
push b
push d
push h
lxi d,outabuf+3
outadgt: mvi b,-1
outdivmod: inr b
sui 10
jnc outdivmod
adi 10+'0'
dcx d
stax d
mov a,b
ana a
jnz outadgt
call outs
jmp regrestore
outabuf: db '***$' ; Room for ASCII number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the character in A followed by a space, preserving
;;; registers.
outaspace: call outa
push psw
mvi a,' '
call outa
pop psw
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the character in A, preserving all registers.
outa: push psw
push b
push d
push h
mov e,a
mvi c,putch
call 5
regrestore: pop h
pop d
pop b
pop psw
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Strings
usage: db 'Usage: FLIP [3..8], number is board size.$'
presskeys: db 'Please press some keys to generate a random state...$'
welcome: db 'done.',13,10,13,10
db '*** FLIP THE BITS *** ',13,10
db '--------------------- ',
newline: db 13,10,'$'
smoves: db 13,10,13,10,'Your flips: $'
sgoal: db 9,'Goal: $'
sboardhdr: db '--Board------------',9,'--Goal-------------',13,10,'$'
prompt: db 'Press line or column to flip, or Q to quit: $'
nope: db 8,32,8,7,'$' ; Beep and erase input
win: db 13,10,7,7,7,'You win!$'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Data
boardsz: ds 1 ; This will hold the board size
sysflips: ds 1 ; How many flips the system did
usrflips: ds 1 ; How many flips the user did
xabcdat: ds 4 ; RNG state
board: equ $
goal: equ board + 64 ; Max. 8*8 board</syntaxhighlight>
 
{{out}}
 
Example game:
<pre>A>flip 3
Please press some keys to generate a random state...done.
 
*** FLIP THE BITS ***
---------------------
 
 
Your flips: 0 Goal: 20
--Board------------ --Goal-------------
A B C A B C
1 0 0 0 1 0 1 1
2 0 0 0 2 1 0 0
3 1 1 1 3 0 1 1
Press line or column to flip, or Q to quit: a
 
Your flips: 1 Goal: 20
--Board------------ --Goal-------------
A B C A B C
1 1 0 0 1 0 1 1
2 1 0 0 2 1 0 0
3 0 1 1 3 0 1 1
Press line or column to flip, or Q to quit: 1
You win!
A></pre>
 
=={{header|8086 Assembly}}==
 
This program runs under MS-DOS and takes the board size from the command line.
<syntaxhighlight lang="asm"> bits 16
cpu 8086
;;; MS-DOS PSP locations
arglen: equ 80h
argstart: equ 82h
;;; MS-DOS system calls
getch: equ 1h
putch: equ 2h
puts: equ 9h
time: equ 2Ch
section .text
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Read board size from command line
cmp byte [arglen],0 ; Command line empty?
je printusage ; Then print usage and stop
mov al,[argstart] ; Get first byte on command line
cmp al,'3' ; <3?
jb printusage ; Then print usage and stop
cmp al,'8' ; >8?
ja printusage ; Then print usage and stop
sub al,'0' ; Make number from ASCII
mov [boardsz],al ; Store the board size
mov ah,puts ; If we made it here, print the
mov dx,welcome ; welcome banner.
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Generate random board
call xabcinit ; Initialize the RNG with system time
mov si,board
xor bx,bx
genboard: call xabcrand ; Get random byte
mov ah,al
call xabcrand ; Get another
and ax,0101h ; Keep only the low bit of each byte
mov [si+bx],ax ; And store them
inc bx ; Two bytes onward
inc bx
cmp bl,64 ; Are we done?
jne genboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Copy the board into the goal
mov si,board ; Source is board
mov di,goal ; Destination is goal
mov bx,0 ; Start at the beginning
copyboard: mov ax,[si+bx] ; Load word from board
mov [di+bx],ax ; Store word in goal
inc bx ; We've copied two bytes
inc bx
cmp bl,64 ; Are we done yet?
jne copyboard
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Make an amount of random flips
call xabcrand ; Random number
and al,15 ; [0..15]
add al,5 ; [5..20]
mov [sysflips],al ; Store in memory
mov cl,al ; Flip doesn't touch CL
xor ch,ch ; Set high byte zero
randflips: call xabcrand ; Random number
call flip ; Do a flip (unused bits are ignored)
loop randflips
mov byte [usrflips],0 ; Initialize user flips to 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print game status (moves, goal moves)
status: mov ah,puts
mov dx,smoves
int 21h
mov al,[usrflips]
call printal
mov ah,puts
mov dx,sgoal
int 21h
mov al,[sysflips]
call printal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the game board and goal board
mov ah,puts ; Print the header
mov dx,sboardhdr
int 21h
mov cl,2 ; Print two headers
mov ah,putch ; Indent columns
;;; Print column headers
colheader: mov dl,' '
int 21h
int 21h
mov bh,0 ; Offset
mov bl,'A' ; First letter
.curcol: cmp bh,[boardsz]
mov dl,bl ; Print letter
jb .printcol
mov dl,' ' ; Print space if column not used
.printcol: call dlspace ; Print DL + separator space
inc bl
inc bh
cmp bh,8 ; Done yet?
jb .curcol
mov dl,9 ; Separate the boards with a TAB
int 21h
dec cl ; We need two headers (board and goal)
jnz colheader
mov ah,puts ; Print a newline afterwards
mov dx,newline
int 21h
;;; Print the rows of the boards
xor bh,bh ; Zero high byte of BX
xor cl,cl ; Row index
boardrow: mov ch,2 ; Two rows, board and goal
mov si,board ; Start by printing the game board
.oneboard: xor dh,dh ; Column index
mov dl,cl ; Print row number
add dl,'1'
call dlspace
.curpos: cmp dh,[boardsz] ; Column in use?
mov dl,' ' ; If not, print a space
jae .printpos
mov bl,cl ; Row index
shl bl,1 ; * 8
shl bl,1
shl bl,1
add bl,dh ; Add column index
mov dl,[bx+si] ; Get position from board
add dl,'0' ; Print as ASCII 0 or 1
.printpos: call dlspace
inc dh ; Increment column index
cmp dh,8 ; Are we there yet?
jb .curpos ; If not, print next position
mov dl,9 ; Separate the boards with a TAB
int 21h
dec ch ; Have we printed the goal yet?
mov si,goal ; If not, print the goal next
jnz .oneboard
mov ah,puts ; Print a newline
mov dx,newline
int 21h
inc cl ; Next row
cmp cl,[boardsz] ; Are we there yet?
jb boardrow ; If not, print the next row.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Ask the user for a move
mov ah,puts ; Write the prompt
mov dx,prompt
int 21h
readmove: mov ah,getch ; Read a character
int 21h
or al,32 ; Make letters lowercase
cmp al,'q' ; Quit?
je quit
cmp al,'9' ; Numeric (row) input?
jbe .nummove ; If not, alphabetic (column) input
;;; Letter input (column)
sub al,'a' ; Subtract 'a'
jc invalid ; If it was <'a', invalid input
cmp al,[boardsz] ; Is it on the board?
jae invalid
or al,128 ; Set high bit, for column flip
call flip ; Flip the column
jmp checkwin ; See if the user has won
;;; Number input (row)
.nummove: sub al,'1' ; Rows start at 1.
jc invalid ; If <'1', then invalid
cmp al,[boardsz] ; Is it on the board?
jae invalid
call flip ; Flip the row
;;; Check if the user has won the game
checkwin: xor bh,bh ; Zero high byte of array index
mov dl,[boardsz]
xor ch,ch ; Row coordinate
.row: xor cl,cl ; Column coordinate
.pos: mov bl,ch ; BL = row*8 + col
shl bl,1
shl bl,1
shl bl,1
add bl,cl
mov al,[board+bx] ; Get position from board
cmp al,[goal+bx] ; Compare with corresponding goal pos
jne .nowin ; Not equal: the user hasn't won
inc cl
cmp cl,dl ; Done all positions on row?
jb .pos ; If not, do next.
inc ch
cmp ch,dl ; Done all rows?
jb .row ; If not, do next.
;;; If we get here, the user has won
mov ah,puts
mov dx,win
int 21h
ret
;;; The user hasn't won
.nowin: inc byte [usrflips] ; Record that the user has made a move
jmp status ; Print status and board, get new move
;;; Invalid input
invalid: mov ah,puts
mov dx,nope
int 21h
jmp readmove
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Flip the line or column in AL. If bit 7 set, flip column.
flip: mov si,board ; SI = board
test al,al ; This sets sign flag if bit 7 set
js .column ; If so, flip column.
and al,7 ; We only need the first 3 bits
shl al,1 ; Multiply by 8
shl al,1 ; 8086 does not support 'shl al,3'
shl al,1
xor ah,ah ; High byte 0
mov bx,ax ; BX = offset
mov ah,4 ; 4 words
.rowloop xor word [si+bx],0101h ; Flip two bytes at once
inc bx
inc bx
dec ah
jnz .rowloop
ret
.column: and al,7 ; Flip a column.
xor ah,ah
mov bx,ax ; BX = row offset
mov ah,8 ; 8 bytes (need to do it byte by byte)
.colloop: xor byte [si+bx],01h ; Flip position
add bx,8
dec ah
jnz .colloop
quit: ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print usage and stop
printusage: mov ah,puts
mov dx,usage
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the character in DL followed by a space
dlspace: mov ah,putch
int 21h
mov dl,' '
int 21h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Initialize the random number generator using the system
;;; time.
xabcinit: mov ah,time
int 21h
mov bx,xabcdat
xor [bx],cx
xor [bx+2],dx
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; The "X ABC" random number generator
;;; Return random byte in AL
xabcrand: push bx ; Save registers
push cx
push dx
mov bx,xabcdat ; RNG state pointer
mov cx,[bx] ; CL=x CH=a
mov dx,[bx+2] ; DL=b DH=c
inc cl ; X++
xor ch,dh ; A^=C
xor ch,cl ; A^=X
add dl,ch ; B+=A
mov al,dl
shr al,1 ; B>>1
xor al,ch ; ^A
add al,dh ; +C
mov dh,al ; ->C
mov [bx],cx ; Store new RNG state
mov [bx+2],dx
pop dx ; Restore registers
pop cx
pop bx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Print the byte in AL as a decimal number
printal: mov di,decnum + 3 ; Room in memory for decimal number
mov dl,10 ; Divide by 10
.loop: xor ah,ah ; Zero remainder
div dl ; Divide by 10
add ah,'0' ; Add ASCII 0 to remainder
dec di
mov [di],ah ; Store digit in memory
and al,al ; Done yet?
jnz .loop ; If not, next digit
mov dx,di ; DX = number string
mov ah,puts ; Print the string
int 21h
ret
section .data
decnum: db '***$' ; Decimal number placeholder
usage: db 'Usage: FLIP [3..8], number is board size.$'
welcome: db '*** FLIP THE BITS *** ',13,10
db '--------------------- ',
newline: db 13,10,'$'
smoves: db 13,10,13,10,'Your flips: $'
sgoal: db 9,'Goal: $'
sboardhdr: db 13,10,10,'--Board------------'
db 9,'--Goal-------------',13,10,'$'
prompt: db 13,10,'Press line or column to flip, or Q to quit: $'
nope: db 8,32,8,7,'$' ; Beep and erase input
win: db 13,10,7,7,7,'You win!$'
section .bss
boardsz: resb 1 ; Board size
sysflips: resb 1 ; Amount of flips that the system does
usrflips: resb 1 ; Amount of flips that the user does
xabcdat: resb 4 ; Four byte RNG state
board: resb 64 ; 8*8 board
goal: resb 64 ; 8*8 goal</syntaxhighlight>
 
{{out}}
 
Example game:
 
<pre>C:\>flip86 3
*** FLIP THE BITS ***
---------------------
 
 
Your flips: 0 Goal: 6
 
--Board------------ --Goal-------------
A B C A B C
1 1 1 0 1 1 1 1
2 1 0 0 2 0 1 0
3 1 1 1 3 1 1 0
 
Press line or column to flip, or Q to quit: 2
 
Your flips: 1 Goal: 6
 
--Board------------ --Goal-------------
A B C A B C
1 1 1 0 1 1 1 1
2 0 1 1 2 0 1 0
3 1 1 1 3 1 1 0
 
Press line or column to flip, or Q to quit: c
You win!
C:\></pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">BYTE boardX=[13],boardY=[10],goalX=[22]
 
PROC UpdateBoard(BYTE ARRAY board BYTE side,x0,y0)
BYTE x,y
 
FOR y=0 TO side-1
DO
Position(x0,y0+2+y)
Put(y+'1)
FOR x=0 TO side-1
DO
IF y=0 THEN
Position(x0+2+x,y0)
Put(x+'A)
FI
Position(x0+2+x,y0+2+y)
PrintB(board(x+y*side))
OD
OD
RETURN
 
PROC Randomize(BYTE ARRAY board BYTE len)
BYTE i
 
FOR i=0 TO len-1
DO
board(i)=Rand(2)
OD
RETURN
 
BYTE FUNC Solved(BYTE ARRAY goal,board BYTE side)
BYTE i,len
 
len=side*side
FOR i=0 TO len-1
DO
IF goal(i)#board(i) THEN
RETURN (0)
FI
OD
RETURN (1)
 
PROC FlipRow(BYTE ARRAY board BYTE side,row)
BYTE i,ind
 
IF row>=side THEN RETURN FI
FOR i=0 TO side-1
DO
ind=i+row*side
board(ind)=1-board(ind)
OD
UpdateBoard(board,side,boardX,boardY)
RETURN
 
PROC FlipColumn(BYTE ARRAY board BYTE side,column)
BYTE i,ind
 
IF column>=side THEN RETURN FI
FOR i=0 TO side-1
DO
ind=column+i*side
board(ind)=1-board(ind)
OD
UpdateBoard(board,side,boardX,boardY)
RETURN
 
PROC Wait(BYTE frames)
BYTE RTCLOK=$14
frames==+RTCLOK
WHILE frames#RTCLOK DO OD
RETURN
 
PROC UpdateStatus(BYTE ARRAY goal,board BYTE side)
Position(9,3) Print("Game status: ")
IF Solved(goal,board,side) THEN
Print("SOLVED !")
Sound(0,100,10,5) Wait(5)
Sound(0,60,10,5) Wait(5)
Sound(0,40,10,5) Wait(5)
Sound(0,0,0,0)
ELSE
Print("Shuffled")
FI
RETURN
 
PROC Init(BYTE ARRAY goal,board BYTE side)
BYTE size,i,n
 
size=side*side
Randomize(goal,size)
MoveBlock(board,goal,size)
UpdateBoard(goal,side,goalX,boardY)
 
WHILE Solved(goal,board,side)
DO
FOR i=1 TO 20
DO
n=Rand(side)
IF Rand(2)=0 THEN
FlipRow(board,side,n)
ELSE
FlipColumn(board,side,n)
FI
OD
OD
RETURN
 
PROC Main()
DEFINE SIDE="3"
DEFINE SIZE="9"
BYTE ARRAY board(SIZE),goal(SIZE)
BYTE CRSINH=$02F0 ;Controls visibility of cursor
BYTE k,CH=$02FC ;Internal hardware value for last key pressed
 
Graphics(0)
SetColor(2,0,2)
CRSINH=1 ;hide cursor
Position(boardX,boardY-2) Print("Board")
Position(goalX+1,boardY-2) Print("Goal")
Position(9,19) Print("Space bar - shuffle")
Init(goal,board,SIDE)
UpdateStatus(goal,board,side)
 
DO
k=CH
IF k#$FF THEN
CH=$FF
IF k=31 THEN FlipRow(board,SIDE,0)
ELSEIF k=30 THEN FlipRow(board,SIDE,1)
ELSEIF k=26 THEN FlipRow(board,SIDE,2)
ELSEIF k=63 THEN FlipColumn(board,SIDE,0)
ELSEIF k=21 THEN FlipColumn(board,SIDE,1)
ELSEIF k=18 THEN FlipColumn(board,SIDE,2)
ELSEIF k=33 THEN Init(goal,board,SIDE) FI
 
UpdateStatus(goal,board,SIDE)
FI
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Flipping_bits_game.png Screenshot from Atari 8-bit computer]
 
=={{header|Ada}}==
This solution determines the size of the playground from the command line.
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Command_Line, Ada.Numerics.Discrete_Random;
 
procedure Flip_Bits is
Line 129 ⟶ 1,114:
-- summarize the outcome
Ada.Text_IO.Put_Line("Done after" & Natural'Image(Moves) & " Moves.");
end Flip_Bits;</langsyntaxhighlight>
 
{{out}}
Line 159 ⟶ 1,144:
c
Done after 2 Moves.</pre>
 
=={{header|APL}}==
{{works with|GNU APL}}
 
<syntaxhighlight lang="apl">#!/usr/local/bin/apl -s --
 
∇r←b FlipRow ix ⍝ Flip a row
r←b
r[ix;]←~r[ix;]
 
∇r←b FlipCol ix ⍝ Flip a column
r←b
r[;ix]←~r[;ix]
 
∇r←RandFlip b;ix ⍝ Flip a random row or column
ix←?↑⍴b
→(2|?2)/col
r←b FlipRow ix ⋄ →0
col: r←b FlipCol ix
 
∇s←ttl ShowBoard b;d ⍝ Add row, column indices and title to board
s←'-'⍪⍕(' ',⎕UCS 48+d),(⎕UCS 64+d←⍳↑⍴b)⍪b
s←((2⊃⍴s)↑ttl)⍪s
 
∇b←MkBoard n ⍝ Generate random board
b←(?(n,n)⍴2)-1
 
∇Game;n;board;goal;moves;swaps;in;tgt
⍝⍝ Initialize
⎕RL←(2*32)|×/⎕TS ⍝ random seed from time
→(5≠⍴⎕ARG)/usage ⍝ check argument
→(~'0123456789'∧.∊⍨n←5⊃⎕ARG)/usage
→((3>n)∨8<n←⍎n)/usage
board←goal←MkBoard n ⍝ Make a random board of the right size
swaps←4+?16 ⍝ 5 to 20 swaps
board←(RandFlip⍣swaps)board
moves←0
⎕←'*** Flip the bits! ***'
⎕←'----------------------'
⍝⍝ Print game state
state: ⎕←''
⎕←'Swaps:',moves,' Goal:',swaps
⎕←''
('Board'ShowBoard board),' ',' ',' ',' ','Goal'ShowBoard goal
⍝⍝ Handle move
⍞←'Press line or column to flip, or Q to quit: '
read: in←32⊤∨1⎕FIO[41]1
→(in=⎕UCS'q')/0
→((97≤in)∧(tgt←in-96)≤n)/col
→((49≤in)∧(tgt←in-48)≤n)/row
→read
col: ⍞←⎕UCS in ⋄ board←board FlipCol tgt ⋄ →check
row: ⍞←⎕UCS in ⋄ board←board FlipRow tgt
 
⍝⍝ Check if player won
check: →(board≡goal)/win
moves←moves+1
→state
win: ⎕←'You win!'
→0
usage: ⎕←'Usage:',⎕ARG[4],'[3..8]; number is board size.'
Game
)OFF</syntaxhighlight>
 
{{out}}
 
Example game:
<pre>$ ./flip.apl 3
*** Flip the bits! ***
----------------------
 
Swaps: 0 Goal: 14
 
Board Goal
------- -------
A B C A B C
1 0 0 1 1 1 0 1
2 0 1 0 2 0 0 1
3 1 0 1 3 0 0 1
Press line or column to flip, or Q to quit: 2
 
Swaps: 1 Goal: 14
 
Board Goal
------- -------
A B C A B C
1 0 0 1 1 1 0 1
2 1 0 1 2 0 0 1
3 1 0 1 3 0 0 1
Press line or column to flip, or Q to quit: a
You win!
 
$</pre>
 
=={{header|AutoHotkey}}==
{{incomplete|AutoHotkey|Understood comment on why output is missing, but this is to make that fact more prominent.}}
Uploads are currently disabled, so since a GUI is used, I can't show an example.
<langsyntaxhighlight lang="ahk">size := 3 ; max 26
Gui, Add, Button, , O
Loop, %size%
Line 245 ⟶ 1,332:
GuiClose:
ExitApp
Return</langsyntaxhighlight>
 
=={{header|BASIC}}==
<syntaxhighlight lang="basic">10 DEFINT A-Z
20 PRINT "*** FLIP THE BITS ***"
30 INPUT "Board size";S
40 IF S<3 OR S>8 THEN PRINT "3 <= size <= 8": GOTO 30
50 RANDOMIZE
60 DIM B(S,S),G(S,S)
70 FOR X=1 TO S
80 FOR Y=1 TO S
90 B=INT(.5+RND(1))
100 B(X,Y)=B: G(X,Y)=B
110 NEXT Y,X
120 FOR A=0 TO 10+2*INT(10*RND(1))
130 R=INT(.5+RND(1))
140 N=1+INT(S*RND(1))
150 GOSUB 500
160 NEXT A: M=0
170 PRINT: M=M+1
180 PRINT " ==BOARD==";TAB(20);" ==GOAL=="
190 PRINT " ";: GOSUB 400
200 PRINT TAB(20);" ";: GOSUB 400
210 FOR N=1 TO S
220 FOR A=0 TO 1
230 PRINT TAB(A*20);CHR$(64+N);". ";
240 FOR C=1 TO S: IF A THEN B=G(C,N) ELSE B=B(C,N)
250 PRINT USING "# ";B;
260 NEXT C,A
270 PRINT
280 NEXT N
290 PRINT
300 LINE INPUT "Enter row or column: ";I$
310 IF LEN(I$)<>1 THEN 300 ELSE C=ASC(I$) OR 32
320 IF C<97 THEN N=C-48:R=0 ELSE N=C-96:R=1
330 IF N<1 OR N>S THEN 300 ELSE GOSUB 500
340 W=1=1
350 FOR X=1 TO S:FOR Y=1 TO S
360 W=W AND (B(X,Y)=G(X,Y))
370 NEXT Y,X
380 IF W THEN PRINT:PRINT "You win! Moves:";M:END
390 GOTO 170
400 FOR I=1 TO S: PRINT USING "# ";I;: NEXT I: RETURN
500 IF R THEN 510 ELSE 520
510 FOR I=1 TO S: B(I,N)=1-B(I,N): NEXT I: RETURN
520 FOR I=1 TO S: B(N,I)=1-B(N,I): NEXT I: RETURN</syntaxhighlight>
{{out}}
<pre>*** FLIP THE BITS ***
Board size? 3
Random number seed (-32768 to 32767)? 1
 
==BOARD== ==GOAL==
1 2 3 1 2 3
A. 1 0 1 A. 1 1 0
B. 1 1 1 B. 0 1 1
C. 1 1 1 C. 1 0 0
 
Enter row or column: 2
 
==BOARD== ==GOAL==
1 2 3 1 2 3
A. 1 1 1 A. 1 1 0
B. 1 0 1 B. 0 1 1
C. 1 0 1 C. 1 0 0
 
Enter row or column: 3
 
==BOARD== ==GOAL==
1 2 3 1 2 3
A. 1 1 0 A. 1 1 0
B. 1 0 0 B. 0 1 1
C. 1 0 0 C. 1 0 0
 
Enter row or column: B
 
You win! Moves: 3 </pre>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
static $( randstate = ? $)
 
let rand() = valof
$( randstate := random(randstate)
resultis randstate >> 7
$)
 
let showboard(size, board, goal) be
$( writes(" == BOARD == ")
for i=1 to 19 do wrch(' ')
writes(" == GOAL ==*N")
for i=1 to 2
$( writes(" ")
for j=1 to size do writef(" %N",j)
test i=1 for j=1 to 30-2*size do wrch(' ') or wrch('*N')
$)
for row=0 to size-1 for i=1 to 2
$( writef("%C.", 'A'+row)
for col=0 to size-1 do
writef(" %N", (i=1->board,goal)!(row*size+col))
test i=1 for j=1 to 30-2*size do wrch(' ') or wrch('*N')
$)
$)
 
let readmove(size) = valof
$( let ch = ? and x = ?
writes("Enter row or column, or Q to quit: ")
ch := rdch()
unless ch = '*N' x := rdch() repeatuntil x = '*N'
ch := ch | 32;
if ch = 'q' | ch = endstreamch finish
if 0 <= (ch-'1') < size | 0 <= (ch-'a') < size resultis ch
$) repeat
 
let flip(size, board, n, col) be
test col
do flipcol(size, board, n)
or fliprow(size, board, n)
and flipcol(size, board, n) be
for i=0 to size-1 do
board!(i*size+n) := 1-board!(i*size+n)
and fliprow(size, board, n) be
for i=0 to size-1 do
board!(n*size+i) := 1-board!(n*size+i)
let makegoal(size, goal) be
for i=0 to size*size-1 do goal!i := rand() & 1
 
let makeboard(size, board, goal) be
$( for i=0 to size*size-1 do board!i := goal!i
for i=0 to 10+2*(rand() & 15) do
flip(size, board, rand() rem size, rand() & 1)
$)
 
let win(size, board, goal) = valof
$( for i=0 to size*size-1
unless board!i = goal!i resultis false
resultis true
$)
 
let play(size, board, goal) be
$( let moves = 0 and move = ?
$( showboard(size, board, goal)
wrch('*N')
if win(size, board, goal)
$( writef("You won in %N moves!*N", moves)
return
$)
moves := moves + 1
move := readmove(size)
test '0' <= move <= '9'
do flipcol(size, board, move-'1')
or fliprow(size, board, move-'a')
$) repeat
$)
 
let start() be
$( let board = vec 63 and goal = vec 63
let size = ?
writef("****** FLIP THE BITS *******N")
$( writef("Size (3-8)? ")
size := readn()
$) repeatuntil 3 <= size <= 8
writef("Random number seed? ")
randstate := readn()
wrch('*N')
makegoal(size, goal)
makeboard(size, board, goal)
play(size, board, goal)
$)</syntaxhighlight>
{{out}}
<pre>*** FLIP THE BITS ***
Size (3-8)? 3
Random number seed? 0
 
== BOARD == == GOAL ==
1 2 3 1 2 3
A. 1 0 1 A. 0 1 1
B. 0 1 0 B. 1 0 0
C. 1 0 0 C. 1 0 1
 
Enter row or column, or Q to quit: 3
== BOARD == == GOAL ==
1 2 3 1 2 3
A. 1 0 0 A. 0 1 1
B. 0 1 1 B. 1 0 0
C. 1 0 1 C. 1 0 1
 
Enter row or column, or Q to quit: A
== BOARD == == GOAL ==
1 2 3 1 2 3
A. 0 1 1 A. 0 1 1
B. 0 1 1 B. 1 0 0
C. 1 0 1 C. 1 0 1
 
Enter row or column, or Q to quit: B
== BOARD == == GOAL ==
1 2 3 1 2 3
A. 0 1 1 A. 0 1 1
B. 1 0 0 B. 1 0 0
C. 1 0 1 C. 1 0 1
 
You won in 3 moves!</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">
<lang c>
#include <stdio.h>
#include <stdlib.h>
Line 364 ⟶ 1,654:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 399 ⟶ 1,689:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <time.h>
#include <iostream>
Line 492 ⟶ 1,782:
int main( int argc, char* argv[] )
{ srand( time( NULL ) ); flip g; g.play( 3, 3 ); return system( "pause" ); }
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 514 ⟶ 1,804:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn cols [board]
(mapv vec (apply map list board)))
 
Line 578 ⟶ 1,868:
(println "Target")
(print-board target-board)
(play-game target-board (play-rand target-board 3) 0))))</langsyntaxhighlight>
 
{{out}}
Line 605 ⟶ 1,895:
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.random, std.ascii, std.string, std.range,
std.algorithm, std.conv;
 
Line 674 ⟶ 1,964:
 
"\nWell done!".writeln;
}</langsyntaxhighlight>
{{out}}
<pre>T prints the target, and Q exits.
Line 703 ⟶ 1,993:
{{works with|Elixir|1.1}}
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Flip_game do
@az Enum.map(?a..?z, &List.to_string([&1]))
@in2i Enum.concat(Enum.map(1..26, fn i -> {to_string(i), i} end),
Line 769 ⟶ 2,059:
end
 
Flip_game.play(3)</langsyntaxhighlight>
 
{{out}}
Line 805 ⟶ 2,095:
You solved the game in 3 moves
</pre>
 
=={{header|FOCAL}}==
 
<syntaxhighlight lang="focal">01.10 T "FLIP THE BITS"!"-------------"!!;S M=0
01.20 A "SIZE",N;I (N-2)1.2;I (8-N)1.2
01.30 F I=0,N*N-1;D 3.2;S G(I)=A;S B(I)=A
01.35 D 3.3;S L=FITR(A*5)*2+6;F K=0,L;D 3.1;S Z=A;D 3.2;D 4.4
01.40 S A=0;F I=0,N*N-1;S A=A+FABS(G(I)-B(I))
01.42 T "MOVES",%3,M,!;S M=M+1
01.45 I (0-A)1.5;T !"YOU WIN!"!;Q
01.50 D 2
01.55 A "FLIP ROW (A) OR COLUMN (B)",A;S A=A-1;I (1-A)1.5
01.60 A "WHICH",Z;S Z=Z-1;I (N-A)1.6
01.65 D 4.4;G 1.4
 
02.10 T "--BOARD--";F A=1,N*2-5;T " "
02.14 T "--GOAL--"!" ";F A=0,N-1;T " ";D 5
02.15 T " ";F A=0,N-1;T " ";D 5
02.20 F R=0,N-1;S A=R;T !;D 2.4;T " ";D 2.5
02.30 T !!;R
02.40 D 5;F C=0,N-1;D 2.6
02.50 D 5;F C=0,N-1;D 2.7
02.60 I (B(R*N+C)-1)2.8;T " 1"
02.70 I (G(R*N+C)-1)2.8;T " 1"
02.80 T " 0"
 
03.10 D 3.3;S A=FITR(A*N)
03.20 D 3.3;S A=FITR(A+0.5)
03.30 S A=FABS(FRAN())*10;S A=A-FITR(A)
 
04.40 I (A-1)4.5,4.6
04.50 F I=0,N-1;S B(Z*N+I)=1-B(Z*N+I)
04.60 F I=0,N-1;S B(I*N+Z)=1-B(I*N+Z)
 
05.10 I (A-7)5.2;T "H";R
05.20 I (A-6)5.3;T "G";R
05.30 I (A-5)5.4;T "F";R
05.40 I (A-4)5.5;T "E";R
05.50 I (A-3)5.6;T "D";R
05.60 I (A-2)5.7;T "C";R
05.70 I (A-1)5.8;T "B";R
05.80 T "A"</syntaxhighlight>
 
{{out}}
 
<pre>FLIP THE BITS
-------------
 
SIZE:3
MOVES= 0
--BOARD-- --GOAL--
A B C A B C
A 1 0 1 A 0 1 1
B 1 1 0 B 0 0 0
C 0 0 1 C 0 0 0
 
FLIP ROW (A) OR COLUMN (B):A
WHICH:A
MOVES= 1
--BOARD-- --GOAL--
A B C A B C
A 0 1 0 A 0 1 1
B 1 1 0 B 0 0 0
C 0 0 1 C 0 0 0
 
FLIP ROW (A) OR COLUMN (B):A
WHICH:B
MOVES= 2
--BOARD-- --GOAL--
A B C A B C
A 0 1 0 A 0 1 1
B 0 0 1 B 0 0 0
C 0 0 1 C 0 0 0
 
FLIP ROW (A) OR COLUMN (B):B
WHICH:C
MOVES= 3
 
YOU WIN!</pre>
 
 
 
=={{header|Forth}}==
{{works with|gforth|0.7.3}}
 
===8x8 board in 64 bits Version===
Board size limited to 8x8, stored in only one cell (64 bits) variable.
<syntaxhighlight lang="Forth">
require random.fs
 
0 value board-size
variable target
variable board
variable moves
 
: moves-reset 0 moves ! ;
: moves+ 1 moves +! ;
: .moves ." You have made " moves @ . ." moves." ;
 
: target-gen ( -- ) rnd target ! ;
 
: row-flip ( n -- )
8 * 255 swap lshift
board @ xor board ! ;
 
: column-flip ( n -- )
1 swap lshift
8 0 do dup 8 lshift or loop
board @ xor board ! ;
 
: target>board ( -- ) target @ board ! ;
 
: board-shuffle ( -- )
board-size dup * 0 do
board-size random 2 random if row-flip else column-flip then
loop ;
 
: ask-move ( -- char )
cr ." choose row [0-" board-size [char] 0 + 1- emit
." ] or column [a-" board-size [char] a + 1- emit
." ]: "
key ;
 
: do-move ( char -- )
dup emit
dup [char] a dup board-size + within
if dup [char] a - column-flip
else
dup [char] 0 dup board-size + within
if dup [char] 0 - row-flip
else ." - this move is not permitted!"
then then
cr drop
;
 
: .header ( -- ) cr ." Target: " board-size 2 * spaces ." Board:" ;
: .column-header ( -- ) board-size 0 do i [char] a + emit space loop ;
: .row-header ( n -- ) . ." - " ;
: .row ( board@ n -- ) dup .row-header 8 * rshift board-size 0 do dup 1 and . 2/ loop drop ;
: .boards
.header cr
4 spaces .column-header 8 spaces .column-header cr
board-size 0 do
target @ i .row 4 spaces board @ i .row cr
loop
;
 
: ?win ( -- f )
0 board-size 0 do 2* 1+ loop
board-size 1 do dup 8 lshift or loop
dup target @ and
swap board @ and =
;
 
: game-loop
begin
.boards .moves
ask-move do-move moves+
?win until
." You win after " moves @ . ." moves!"
;
 
: flip-bit-game ( n -- )
to board-size
target-gen target>board board-shuffle
moves-reset
game-loop
;
</syntaxhighlight>
 
{{out}}
<pre>
3 flip-bit-game
Target: Board:
a b c a b c
0 - 0 0 1 0 - 1 0 0
1 - 1 0 1 1 - 1 1 1
2 - 1 0 0 2 - 0 0 1
You have made 0 moves.
choose row [0-2] or column [a-c]: 0
 
Target: Board:
a b c a b c
0 - 0 0 1 0 - 0 1 1
1 - 1 0 1 1 - 1 1 1
2 - 1 0 0 2 - 0 0 1
You have made 1 moves.
choose row [0-2] or column [a-c]: 2
 
Target: Board:
a b c a b c
0 - 0 0 1 0 - 0 1 1
1 - 1 0 1 1 - 1 1 1
2 - 1 0 0 2 - 1 1 0
You have made 2 moves.
choose row [0-2] or column [a-c]: b
You win after 3 moves! ok
</pre>
 
=== board in a cells array Version===
No size limitation. Board stored in a cells array (use of 64 bits for a bit...). Memory not freed.
 
<syntaxhighlight lang="Forth">
require random.fs
 
0 value board-size
0 value target
0 value board
variable moves
 
: moves-reset 0 moves ! ;
: moves+ 1 moves +! ;
: .moves ." You have made " moves @ . ." moves." ;
 
: allot-board ( -- addr ) here board-size dup * cells allot ;
 
: target-gen ( -- )
board-size dup * 0 do
2 random [char] 0 + target i cells + !
loop
;
 
: row-flip ( board n -- )
board-size * cells +
dup board-size cells + swap do
i dup @ 1 xor swap !
cell +loop
;
 
: column-flip ( board n -- )
cells +
dup board-size dup * cells + swap do
i dup @ 1 xor swap !
board-size cells +loop
;
 
: target>board ( -- )
board-size dup * cells 0 do
target i + @ board i + !
cell +loop
;
 
: board-shuffle ( -- )
board-size dup * 0 do
board board-size random 2 random if row-flip else column-flip then
loop
;
 
: ask-move ( -- char )
cr ." choose row [0-" board-size [char] 0 + 1- emit
." ] or column [a-" board-size [char] a + 1- emit
." ]: "
key ;
 
: do-move ( char -- )
dup emit
dup [char] a dup board-size + within
if dup board swap [char] a - column-flip
else
dup [char] 0 dup board-size + within
if dup board swap [char] 0 - row-flip
else ." - this move is not permitted!"
then then
cr drop
;
 
: .header ( -- ) cr ." Target: " board-size 2 * spaces ." Board:" ;
: .column-header ( -- ) board-size 0 do i [char] a + emit space loop ;
: .row-header ( n -- ) . ." - " ;
: .bit ( board row col -- ) board-size * + cells + @ emit space ;
: .row ( board n -- ) dup .row-header board-size 0 do 2dup i swap .bit loop 2drop ;
: .boards
.header cr
4 spaces .column-header 8 spaces .column-header cr
board-size 0 do
target i .row 4 spaces board i .row cr
loop
;
 
: ?win ( -- f )
board-size dup * 0 do
target i cells + @ board i cells + @
<> if false unloop exit then
loop true
;
 
: game-loop
begin
.boards .moves
ask-move do-move moves+
?win until
." You win after " moves @ . ." moves!"
;
 
: flip-bit-game ( n -- )
to board-size
allot-board to target
allot-board to board
target-gen
target>board
board-shuffle
moves-reset
game-loop
;
</syntaxhighlight>
{{out}}
<pre>
3 flip-bit-game
Target: Board:
a b c a b c
0 - 0 0 0 0 - 1 0 1
1 - 0 1 1 1 - 0 0 1
2 - 1 1 0 2 - 0 1 1
You have made 0 moves.
choose row [0-2] or column [a-c]: 0
 
Target: Board:
a b c a b c
0 - 0 0 0 0 - 0 1 0
1 - 0 1 1 1 - 0 0 1
2 - 1 1 0 2 - 0 1 1
You have made 1 moves.
choose row [0-2] or column [a-c]: b
 
Target: Board:
a b c a b c
0 - 0 0 0 0 - 0 0 0
1 - 0 1 1 1 - 0 1 1
2 - 1 1 0 2 - 0 0 1
You have made 2 moves.
choose row [0-2] or column [a-c]: 2
You win after 3 moves! ok
</pre>
 
 
 
 
 
=={{header|Fortran}}==
This version uses some routines (like rand(), srand() and date_and_time()) from the GNU Fortran compiler. Formats are used to print data on the screen in an appropriate manner. The number of rows (or columns) is a variable and the current implementation allows for any number between 1 and 10. Incorrect inputs are also verified.
 
<syntaxhighlight lang="fortran">
<lang Fortran>
!Implemented by Anant Dixit (October 2014)
program flipping_bits
Line 1,007 ⟶ 2,634:
end do
end subroutine
</syntaxhighlight>
</lang>
 
Example:
Line 1,091 ⟶ 2,718:
</pre>
 
=={{header|GoFreeBASIC}}==
{{trans|QB64}}
<syntaxhighlight lang="vb">Dim Shared As Integer celdasXLado, contarMovs
Dim Shared As String movsValidos, inicioBS, actualBS, objetivoBS
 
Sub mostrarTablero (fila As Integer, columna As Integer, junto As String, titulo As String)
<lang go>package main
Dim As Integer i, j
 
Locate fila - 1, columna: Print titulo
For i = 1 To celdasXLado
Locate fila, columna + 2 * (i-1) + 3: Print Mid(movsValidos, i, 1);
Next i
Print
For i = 1 To celdasXLado
Locate fila + i, columna - 1: Print Str(i);
For j = 1 To celdasXLado
Locate fila + i, columna + 2 * j: Print " " + Mid(junto, (i-1) * celdasXLado + j, 1);
Next j
Print
Next i
End Sub
 
Sub mostrarEstado
Color 9: mostrarTablero 2, 2, actualBS, "Current:"
Color 12: mostrarTablero 2, 2 + 2 * celdasXLado + 6, objetivoBS, " Target:"
Color 13: Print !"\n Number of moves taken so far is " + Str(contarMovs)
Color 14
End Sub
 
Function Pistas() As String 'compare the currentB to targetB and suggest letter or digit or done
Dim As Integer i, j
Dim As Boolean flag = False
Dim As String r, actualBitS, objetivoBitS
For i = 1 To 2 * celdasXLado 'check cols first then rows as listed in movsValidos
r = Mid(movsValidos, i, 1)
If i <= celdasXLado Then
actualBitS = Mid(actualBS, i, 1): objetivoBitS = Mid(objetivoBS, i, 1)
If actualBitS <> objetivoBitS Then flag = False: Exit For
Else
j = i - celdasXLado
actualBitS = Mid(actualBS, (j - 1) * celdasXLado + 1, 1)
objetivoBitS = Mid(objetivoBS, (j - 1) * celdasXLado + 1, 1)
If actualBitS <> objetivoBitS Then flag = False: Exit For
End If
Next i
Pistas = Iif(flag, r, "Done?")
End Function
 
Sub Centrar (fila As Integer, texto As String) 'center print at fila
Locate fila, (80 - Len(texto)) / 2: Print texto;
End Sub
 
Sub vcls 'print the screen to file then clear it
Dim As String sc(23), scan
Dim As Integer lineas, t, final, i
For lineas = 1 To 23
For t = 1 To 80: scan &= Chr(Screen(lineas, t)): Next t
sc(lineas) = Rtrim(scan)
scan = ""
Next lineas
For final = 23 To 1 Step -1
If sc(final) <> "" Then Exit For
Next final
Print #3, ""
For i = 1 To final: Print #3, sc(i): Next i
Print #3, "": Print #3, String(80, "-"): Cls
End Sub
 
Function TeclaPulsada() As String 'just want printable characters
Dim As String KBD = ""
While Len(KBD) = 0
KBD = Inkey
If Len(KBD) Then 'press something so respond
If Len(KBD) = 2 Or Asc(KBD) > 126 Or Asc(KBD) < 32 Then KBD = "*"
End If
Wend
Return KBD
End Function
 
Function inicioTablero() As String
Dim As String r
For i As Integer = 1 To celdasXLado ^ 2
r &= Ltrim(Str(Int(Rnd * 2)))
Next i
Return r
End Function
 
Sub hacerMovim (moveS As String)
Dim As Uinteger ac = Asc(moveS)
Dim As Integer i, columna, fila
Dim As String bitS
If ac > 96 Then 'letter
columna = ac - 96
For i = 1 To celdasXLado
bitS = Mid(actualBS, (i - 1) * celdasXLado + columna, 1)
Mid(actualBS, (i-1) * celdasXLado + columna, 1) = Iif(bitS = "0", "1", "0")
Next
Else 'number
fila = ac - 48
For i = 1 To celdasXLado
bitS = Mid(actualBS, (fila-1) * celdasXLado + i, 1)
Mid(actualBS, (fila-1) * celdasXLado + i, 1) = Iif(bitS = "0", "1", "0")
Next i
End If
End Sub
 
Function hacerObjetivo() As String
While actualBS = inicioBS
For i As Integer = 1 To celdasXLado * celdasXLado
Dim As String mS = Mid(movsValidos, Int(Rnd * Len(movsValidos)) + 1, 1)
hacerMovim mS
Next i
Wend
Return actualBS
End Function
 
Sub Intro
Dim As Integer i
Dim As String inS
Close
Open "Copy Flipping Bits Game.txt" For Output As #3
celdasXLado = 0: movsValidos = "": contarMovs = 0
Color 9: Centrar 3, "Flipping Bits Game (with AI!) JHG 31/05/2023"
Color 5
Centrar 5, "You will be presented with a square board marked Current and"
Centrar 6, "another marked Target. The object of the game is to match"
Centrar 7, "the Current board to Target in the least amount of moves."
Centrar 9, "To make a move, enter a letter for a column to flip or"
Centrar 10, "a digit for a fila to flip. In a flip, all 1's are"
Centrar 11, "changed to 0's and all 0's changed to 1's."
Centrar 13, "You may enter 0 or q at any time to quit."
Centrar 14, "You may press ? when prompted for move to get a hint."
Centrar 15, "You may press ! to have the program solve the puzzle."
Color 14: Print: Print
While celdasXLado < 2 Or celdasXLado > 9
Locate Csrlin, 13: Print "Please press how many cells you want per side 2 to 9 > ";
inS = TeclaPulsada: Print inS : Sleep .4
If inS = "0" Or inS = "q" Then End Else celdasXLado = Val(inS)
Wend
vcls
For i = 1 To celdasXLado: movsValidos = movsValidos + Chr(96 + i) : Next i
For i = 1 To celdasXLado: movsValidos = movsValidos + Ltrim(Str(i)): Next i
inicioBS = inicioTablero
actualBS = inicioBS
objetivoBS = hacerObjetivo
actualBS = inicioBS
End Sub
 
Sub MenuPrincipal
Dim As String SiNo, mS, mvS
Dim As Boolean mostrarSolucion = False, salir = False
Do
mostrarEstado
If actualBS = objetivoBS Then 'game done!
Print !"\n Congratulations, done in"; contarMovs; " moves."
Print !"\n Press y for yes, if you want to start over > ";
SiNo = TeclaPulsada: Print SiNo: Sleep .4: vcls
If SiNo = "y" Then Intro Else salir = True
Else 'get next move
mS = " "
While Instr(movsValidos, mS) = 0
Print !"\n Press a lettered column or a numbered fila to flip (or 0,q,?,!) > ";
mS = TeclaPulsada: Print mS: Sleep .4
If mS = "!" Then
mostrarSolucion = True: mS = " ": Exit While
Elseif mS = "?" Then mS = " ": Centrar Csrlin, "Hint: " + Pistas
Elseif mS = "0" Or mS = "q" Then vcls: Close: End
Elseif mS = "" Then mS = " "
End If
Wend
If mostrarSolucion Then 'run the solution from hints function
mostrarSolucion = False: mvS = Pistas
Centrar Csrlin + 1, "For the next move, the AI has chosen: " + mvS
Centrar Csrlin + 1, "Running the solution with 4 sec screen sleeps..."
Sleep 4: vcls
While mvS <> "Done?"
contarMovs += 1
hacerMovim mvS
mostrarEstado
mvS = Pistas
Centrar Csrlin + 1, "For the next move, the AI has chosen: " + mvS
Centrar Csrlin + 1, "Running the solution with 4 sec screen sleeps..."
Sleep 4: vcls
Wend
mostrarEstado
Centrar Csrlin + 1, "Done! Current board matches Target"
Centrar Csrlin + 1, "Press y for yes, if you want to start over: > "
SiNo = TeclaPulsada: Print SiNo: Sleep .4: vcls
If SiNo = "y" Then Intro Else salir = True
Else
vcls
contarMovs += 1
hacerMovim mS
End If
End If
Loop Until salir
Close
End Sub
 
'--- Programa Principal ---
Randomize Timer
Intro
MenuPrincipal
End
'--------------------------</syntaxhighlight>
{{out}}
<pre>Similar to QB64 entry.</pre>
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
Line 1,214 ⟶ 3,055:
}
return o
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,264 ⟶ 3,105:
=={{header|Haskell}}==
Maximum game size is 9x9 because the array indices are the characters 1 until 9.
<langsyntaxhighlight Haskelllang="haskell">import Data.List (intersperse)
 
import System.Random (randomRIO)
Line 1,378 ⟶ 3,219:
tryAgain = do
putStrLn ": Invalid row or column."
turns goal current moves</langsyntaxhighlight>
{{Out}}
<pre>Select a board size (1 - 9).
Line 1,419 ⟶ 3,260:
Using J's command line as the game ui:
 
<langsyntaxhighlight Jlang="j">start=:3 :0
Moves=:0
N=:i.y
Line 1,439 ⟶ 3,280:
Board;End
end.
)</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight Jlang="j"> start 3
┌─────┬─────┐
│1 1 1│1 0 1│
Line 1,458 ⟶ 3,299:
move '1'
3 moves
yes</langsyntaxhighlight>
 
Note that any size game may be generated but this version only recognizes column flips for the first ten columns.
Line 1,465 ⟶ 3,306:
[[File:Flipping_bits_java.gif|200px|thumb|right]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.awt.*;
import java.awt.event.*;
import java.util.*;
Line 1,619 ⟶ 3,460:
});
}
}</langsyntaxhighlight>
<pre>The target
[0, 1, 0]
Line 1,634 ⟶ 3,475:
[0, 1, 0]
[0, 1, 0]</pre>
 
=={{header|JavaScript}}==
<langsyntaxhighlight JavaScriptlang="javascript">function numOfRows(board) { return board.length; }
function numOfCols(board) { return board[0].length; }
function boardToString(board) {
Line 1,730 ⟶ 3,572:
alert('Completed in ' + moves + ' moves.');
}
}</langsyntaxhighlight>
<pre>Try to match both boards.
Enter `r<num>` or `c<num>` to manipulate a row or col or enter `q` to quit.
Line 1,779 ⟶ 3,621:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">module FlippingBitsGame
 
using Printf, Random
Line 1,880 ⟶ 3,722:
 
FlippingBitsGame.play()
</langsyntaxhighlight>{{output}}
<pre>Insert the size of the matrix (nrow [> 1] *space* ncol [> 1]):3 3
 
Line 1,926 ⟶ 3,768:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.util.Random
Line 2,017 ⟶ 3,859:
val plural = if (flips == 1) "" else "s"
println("You've succeeded in $flips flip$plural")
}</langsyntaxhighlight>
 
{{out}}
Line 2,067 ⟶ 3,909:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">
target, board, moves, W, H = {}, {}, 0, 3, 3
 
Line 2,163 ⟶ 4,005:
math.randomseed( os.time() )
play()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,198 ⟶ 4,040:
=={{header|Maple}}==
Click [http://maplecloud.maplesoft.com/application.jsp?appId=5721146878066688 here] to play this game online.
<langsyntaxhighlight lang="maple">FlippingBits := module()
export ModuleApply;
local gameSetup, flip, printGrid, checkInput;
Line 2,304 ⟶ 4,146:
end module:
 
FlippingBits(3);</langsyntaxhighlight>
{{out}}
<pre>
Line 2,331 ⟶ 4,173:
You win!! Press enter to play again or type END to quit.
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[PermuteState]
PermuteState[state_, {rc_, n_Integer}] := Module[{s},
s = state;
Switch[rc, "R",
s[[n]] = 1 - s[[n]],
"C",
s[[All, n]] = 1 - s[[All, n]]
];
s
]
SeedRandom[1337];
n = 3;
goalstate = state = RandomChoice[{0, 1}, {n, n}];
While[goalstate == state,
permutations = {RandomChoice[{"C", "R"}, 20], RandomInteger[{1, n}, 20]} // Transpose;
state = Fold[PermuteState, state, permutations];
];
i = 0;
history = {state};
Grid[goalstate, ItemSize -> {5, 3}, Frame -> True]
b1 = Button["", state = PermuteState[state, {"C", #}];
AppendTo[history, state]; i++;
If[state === goalstate, MessageDialog["You Won!"];
Print[Grid[#, Frame -> True]] & /@ history]] & /@ Range[n];
b2 = Button["", state = PermuteState[state, {"R", #}];
AppendTo[history, state]; i++;
If[state === goalstate, MessageDialog["You Won!"];
Print[Grid[#, Frame -> True]] & /@ history]] & /@ Range[n];
Dynamic[Grid[
Prepend[MapThread[Prepend, {state, b2}],
Prepend[b1, Row[{"Flips: ", i}]]], Frame -> True
]]</syntaxhighlight>
{{out}}
<pre>0 1 0
1 0 0
1 0 1
 
 
0 0 0
1 1 0
1 1 1
 
 
1 0 0
0 1 0
0 1 1
 
 
1 0 0
1 0 1
0 1 1
 
 
0 1 1
1 0 1
0 1 1</pre>
 
=={{header|MATLAB}}==
Size can be passed in as an argument or entered after a prompt.
<langsyntaxhighlight MATLABlang="matlab">function FlippingBitsGame(n)
% Play the flipping bits game on an n x n array
Line 2,420 ⟶ 4,320:
end
fprintf('\n')
end</langsyntaxhighlight>
{{out}}
Normal play and winning:
Line 2,542 ⟶ 4,442:
 
=={{header|MiniScript}}==
<langsyntaxhighlight MiniScriptlang="miniscript">// Flipping Bits game.
// Transform a start grid to an end grid by flipping rows or columns.
 
Line 2,606 ⟶ 4,506:
flipAny(inp)
end while
print "You did it!"</langsyntaxhighlight>
 
{{out}}
Line 2,633 ⟶ 4,533:
A B C
You did it!</pre>
 
=={{header|Nim}}==
{{trans|Kotlin}}
Translation of Kotlin program with some modifications.
 
<syntaxhighlight lang="nim">import random, strformat, strutils
 
type
Bit = range[0..1]
Board = array[3, array[3, Bit]]
 
 
#---------------------------------------------------------------------------------------------------
 
func flipRow(board: var Board; row: int) =
for cell in board[row].mitems:
cell = 1 - cell
 
#---------------------------------------------------------------------------------------------------
 
func flipCol(board: var Board; col: int) =
for row in board.mitems:
row[col] = 1 - row[col]
 
#---------------------------------------------------------------------------------------------------
 
proc initBoard(target: Board): Board =
 
# Starting from the target we make 9 random row or column flips.
result = target
for _ in 1..9:
if rand(1) == 0:
result.flipRow(rand(2))
else:
result.flipCol(rand(2))
 
#---------------------------------------------------------------------------------------------------
 
proc print(board: Board; label: string) =
 
echo &"{label}:"
echo " | a b c"
echo "---------"
for r, row in board:
stdout.write &"{r + 1} |"
for cell in row: stdout.write &" {cell}"
echo ""
echo ""
 
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
var target, board: Board
 
randomize()
 
# Initialize target.
for row in target.mitems:
for cell in row.mitems:
cell = rand(1)
 
# Initialize board and ensure it differs from the target i.e. game not already over!
while true:
board = initBoard(target)
if board != target:
break
 
target.print("TARGET")
board.print("OPENING BOARD")
 
var flips = 0
while board != target:
 
# Get input from player.
var isRow = true
var n = -1
while n < 0:
stdout.write "Enter row number or column letter to be flipped: "
stdout.flushFile()
let input = stdin.readLine()
let ch = if input.len > 0: input[0].toLowerAscii else: '0'
if ch notin "123abc":
echo "Must be 1, 2, 3, a, b or c"
continue
if ch in '1'..'3':
n = ord(ch) - ord('1')
else:
isRow = false
n = ord(ch) - ord('a')
 
# Update board.
inc flips
if isRow: board.flipRow(n) else: board.flipCol(n)
target.print("\nTARGET")
let plural = if flips == 1: "" else: "S"
board.print(&"BOARD AFTER {flips} FLIP{plural}")
 
let plural = if flips == 1: "" else: "s"
echo &"You’ve succeeded in {flips} flip{plural}"</syntaxhighlight>
 
{{out}}
<pre>TARGET:
| a b c
---------
1 | 1 0 0
2 | 1 0 0
3 | 0 1 1
 
OPENING BOARD:
| a b c
---------
1 | 0 1 0
2 | 1 0 1
3 | 1 0 1
 
Enter row number or column letter to be flipped: a
 
TARGET:
| a b c
---------
1 | 1 0 0
2 | 1 0 0
3 | 0 1 1
 
BOARD AFTER 1 FLIP:
| a b c
---------
1 | 1 1 0
2 | 0 0 1
3 | 0 0 1
 
Enter row number or column letter to be flipped: 2
 
TARGET:
| a b c
---------
1 | 1 0 0
2 | 1 0 0
3 | 0 1 1
 
BOARD AFTER 2 FLIPS:
| a b c
---------
1 | 1 1 0
2 | 1 1 0
3 | 0 0 1
 
Enter row number or column letter to be flipped: b
 
TARGET:
| a b c
---------
1 | 1 0 0
2 | 1 0 0
3 | 0 1 1
 
BOARD AFTER 3 FLIPS:
| a b c
---------
1 | 1 0 0
2 | 1 0 0
3 | 0 1 1
 
You’ve succeeded in 3 flips
</pre>
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">module FlipGame =
struct
type t = bool array array
Line 2,705 ⟶ 4,771:
if not !Sys.interactive then
(Random.self_init ();
play ())</langsyntaxhighlight>
 
{{out}}
Line 2,773 ⟶ 4,839:
valid rows or columns, and disregards any irrelevant text in between.
 
<syntaxhighlight lang="perl">use strict;
<lang perl>#!perl
use strict;
use warnings qw(FATAL all);
use feature 'bitwise';
 
my $n = shift(@ARGV) || 4;
Line 2,798 ⟶ 4,864:
{
for(@rows, @cols) {
$start ^.= $_ if int rand 2;
}
redo if $start eq $goal;
Line 2,838 ⟶ 4,904:
$did_one = 1;
if( /\d/ ) {
$start ^.= $rows[$_-1];
} else {
$_ = ord(lc) - ord('a');
$start ^.= $cols[$_];
}
++$moves_so_far;
Line 2,848 ⟶ 4,914:
}
}
print "You won after $moves_so_far moves.\n";</langsyntaxhighlight>
{{out}}
<pre>$ perl FlippingBitsGame.pl 3
Line 2,871 ⟶ 4,937:
 
The same game could have been won after typing 1 2 c in any order, with multiple lines or even "12c" on a single line.
 
=={{header|Perl 6}}==
{{Works with|rakudo|2016.11}}
Pass in a parameter to set the square size for the puzzle. (Defaults to 4.) Arbitrarily limited to between 1 and 26. Yes, you can choose to solve a 1 element square puzzle, but it won't be very challenging. Accepts upper or lower case letters for columns. Disregards any out-of-range indices. Enter a blank or 0 (zero) to exit.
 
<lang perl6>sub MAIN ($square = 4) {
say "{$square}? Seriously?" and exit if $square < 1 or $square > 26;
my %bits = map { $_ => %( map { $_ => 0 }, ('A' .. *)[^ $square] ) },
(1 .. *)[^ $square];
scramble %bits;
my $target = build %bits;
scramble %bits until build(%bits) ne $target;
display($target, %bits);
my $turns = 0;
while my $flip = prompt "Turn {++$turns}: Flip which row / column? " {
flip $flip.match(/\w/).uc, %bits;
if display($target, %bits) {
say "Hurray! You solved it in $turns turns.";
last;
}
}
}
 
sub display($goal, %hash) {
shell('clear');
say "Goal\n$goal\nYou";
my $this = build %hash;
say $this;
return ($goal eq $this);
}
 
sub flip ($a, %hash) {
given $a {
when any(keys %hash) {
%hash{$a}{$_} = %hash{$a}{$_} +^ 1 for %hash{$a}.keys
};
when any(keys %hash{'1'}) {
%hash{$_}{$a} = %hash{$_}{$a} +^ 1 for %hash.keys
};
}
}
 
sub build (%hash) {
my $string = ' ';
$string ~= sprintf "%2s ", $_ for sort keys %hash{'1'};
$string ~= "\n";
for %hash.keys.sort: +* -> $key {
$string ~= sprintf "%2s ", $key;
$string ~= sprintf "%2s ", %hash{$key}{$_} for sort keys %hash{$key};
$string ~= "\n";
};
$string
}
 
sub scramble(%hash) {
my @keys = keys %hash;
@keys.push: | keys %hash{'1'};
flip $_, %hash for @keys.pick( @keys/2 );
}</lang>
A sample 3 x 3 game might look like this:
<pre>Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 0 0 0
2 1 1 1
3 1 1 1
 
Turn 1: Flip which row / column? 2
 
Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 0 0 0
2 0 0 0
3 1 1 1
 
Turn 2: Flip which row / column? 1
 
Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 1 1 1
2 0 0 0
3 1 1 1
 
Turn 3: Flip which row / column? c
 
Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
Hurray! You solved it in 3 turns.</pre>
 
=={{header|Phix}}==
<langsyntaxhighlight Phixlang="phix">integer w, h
 
string board, target
Line 3,142 ⟶ 5,093:
end while
end procedure
main()</langsyntaxhighlight>
{{out}}
<pre>
Line 3,215 ⟶ 5,166:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">(subscriptrange, stringrange, stringsize):
flip: procedure options (main);
declare n fixed binary;
Line 3,263 ⟶ 5,214:
end;
 
end flip;</langsyntaxhighlight>
{{out}}
<pre>
Line 3,295 ⟶ 5,246:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">"""
Given a %i by %i sqare array of zeroes or ones in an initial
configuration, and a target configuration of zeroes and ones
Line 3,379 ⟶ 5,330:
turns -= 1
else:
print('\nWell done!\nBye.')</langsyntaxhighlight>
 
{{out}}
Line 3,467 ⟶ 5,418:
 
=={{header|QB64}}==
<syntaxhighlight lang="text">
RANDOMIZE TIMER
DIM SHARED cellsPerSide, legalMoves$, startB$, currentB$, targetB$, moveCount
Line 3,647 ⟶ 5,598:
getKey$ = k$
END FUNCTION
</syntaxhighlight>
</lang>
'''Output:'''
<syntaxhighlight lang="text">
Flipping Bits Game, now with AI! b+ 2017-12-18
 
Line 3,741 ⟶ 5,692:
 
--------------------------------------------------------------------------------
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
<syntaxhighlight lang="text">#lang racket
(define (flip-row! pzzl r)
(define N (integer-sqrt (bytes-length pzzl)))
Line 3,814 ⟶ 5,765:
[else (printf "unrecognised character in input: ~s~%" else)
(turn n)])]))
(turn 0))</langsyntaxhighlight>
 
{{out}}
Line 3,835 ⟶ 5,786:
flipping row 2
you won on turn #2</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2016.11}}
Pass in a parameter to set the square size for the puzzle. (Defaults to 4.) Arbitrarily limited to between 1 and 26. Yes, you can choose to solve a 1 element square puzzle, but it won't be very challenging. Accepts upper or lower case letters for columns. Disregards any out-of-range indices. Enter a blank or 0 (zero) to exit.
 
<syntaxhighlight lang="raku" line>sub MAIN ($square = 4) {
say "{$square}? Seriously?" and exit if $square < 1 or $square > 26;
my %bits = map { $_ => %( map { $_ => 0 }, ('A' .. *)[^ $square] ) },
(1 .. *)[^ $square];
scramble %bits;
my $target = build %bits;
scramble %bits until build(%bits) ne $target;
display($target, %bits);
my $turns = 0;
while my $flip = prompt "Turn {++$turns}: Flip which row / column? " {
flip $flip.match(/\w/).uc, %bits;
if display($target, %bits) {
say "Hurray! You solved it in $turns turns.";
last;
}
}
}
 
sub display($goal, %hash) {
shell('clear');
say "Goal\n$goal\nYou";
my $this = build %hash;
say $this;
return ($goal eq $this);
}
 
sub flip ($a, %hash) {
given $a {
when any(keys %hash) {
%hash{$a}{$_} = %hash{$a}{$_} +^ 1 for %hash{$a}.keys
};
when any(keys %hash{'1'}) {
%hash{$_}{$a} = %hash{$_}{$a} +^ 1 for %hash.keys
};
}
}
 
sub build (%hash) {
my $string = ' ';
$string ~= sprintf "%2s ", $_ for sort keys %hash{'1'};
$string ~= "\n";
for %hash.keys.sort: +* -> $key {
$string ~= sprintf "%2s ", $key;
$string ~= sprintf "%2s ", %hash{$key}{$_} for sort keys %hash{$key};
$string ~= "\n";
};
$string
}
 
sub scramble(%hash) {
my @keys = keys %hash;
@keys.push: | keys %hash{'1'};
flip $_, %hash for @keys.pick( @keys/2 );
}</syntaxhighlight>
A sample 3 x 3 game might look like this:
<pre>Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 0 0 0
2 1 1 1
3 1 1 1
 
Turn 1: Flip which row / column? 2
 
Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 0 0 0
2 0 0 0
3 1 1 1
 
Turn 2: Flip which row / column? 1
 
Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 1 1 1
2 0 0 0
3 1 1 1
 
Turn 3: Flip which row / column? c
 
Goal
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
You
A B C
1 1 1 0
2 0 0 1
3 1 1 0
 
Hurray! You solved it in 3 turns.</pre>
=={{header|Red}}==
<syntaxhighlight lang="rebol">
Red []
random/seed now/time/precise ;; start random generator
kRows: kCols: 3 ;; define board size, 3x3 upto 9x9 possible
;; create series of 3 empty blocks:
loop kRows [ append/only board: [] copy [] ] ;; ( this is actually a bit tricky, normally you'd have to use "copy" [] inside a loop )
kValid: "1A" ;; generate string for input validation "321ABC"
loop (kRows - 1 ) [insert kValid (first kValid) + 1 ]
loop (kCols - 1 ) [append kValid (last kValid) + 1 ]
repeat row kRows [ loop kCols [ append board/:row -1 + random 2 ] ] ;; fill board with random 0 / 1
;;--------------------------------------
xorme: func ['val][ set val 1 xor get val ] ;; function: flip the given board position
;;--------------------------------------
flip: func [ what [string!] ] [ ;; flip complete row or column of board
row: -48 + to-integer first what ;; convert string to integer row/column index
if row <= kRows [ repeat col kCols [ xorme board/:row/:col] return 0 ]
repeat row2 kRows [ xorme board/:row2/(row - 16)]
]
;;--------------------------------------
showboard: func [title [string!] b] [ ;; function: show board name + board or target
prin [title newline newline" " letter: #"A" ] ;; ( prin doesn't print newline at end )
loop ( kCols - 1) [ prin ["" letter: letter + 1] ] print "" ;; print column letters
repeat row kRows [ ;; print one row
prin row ;; first print row number
repeat col kCols [ prin ["" b/:row/:col ]]
print ""
]
]
 
showboard "Target" target: copy/deep board ;; create target as copy from board and show
random kvalid
repeat pos 3 [flip copy/part skip kvalid pos 1] ;; now flip board 3 times at random row/column
 
run: -1
forever [
showboard "Board" board
if board = target [ Print ["You solved it in" run + 1 "move(s) !" ] halt ] ;; count last move
print [newline "moves:" run: run + 1 ] ;; show moves taken so far
until [ find kvalid inp: uppercase ask "Enter Row No or Column Letter to flip ?" ] ;; read valid input character
flip inp
] ;; 42 lines :- )
</syntaxhighlight>
{{out}}
<pre>
Target
A B C
1 0 1 0
2 1 1 0
3 1 1 0
 
Board
A B C
1 1 1 0
2 1 0 1
3 1 0 1
 
moves: 0
Enter Row No or Column Letter to flip ?1
 
Board
A B C
1 0 0 1
2 1 0 1
3 1 0 1
 
moves: 1
Enter Row No or Column Letter to flip ?C
 
Board
A B C
1 0 0 0
2 1 0 0
3 1 0 0
 
moves: 2
Enter Row No or Column Letter to flip ?B
 
Board
A B C
1 0 1 0
2 1 1 0
3 1 1 0
You solved it in 3 move(s) !
(halted)
</pre>
 
=={{header|REXX}}==
Line 3,842 ⟶ 5,997:
<br>Programming note: &nbsp; none of the command line parameters &nbsp; ('''N''' &nbsp; and &nbsp; '''u''') &nbsp; are checked for errors (so as to make the
<br>program simpler). &nbsp; A fair amount of coding was added to check for a legal "move".
<langsyntaxhighlight lang="rexx">/*REXX program presents a "flipping bit" puzzle. The user can solve via it via C.L. */
parse arg N u seed . /*get optional arguments from the C.L. */
if N=='' | N=="," then N=3 /*Size given? Then use default of 3.*/
Line 3,910 ⟶ 6,065:
if tell then call hdr right(r, 2) ' │'_ tx; _= /*show the grid? */
end /*r*/ /*show a grid row.*/
if tell then say; return $ /*show blank line?*/</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input of: &nbsp; &nbsp; <tt> 3 </tt>}}
 
Line 3,991 ⟶ 6,146:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
load "guilib.ring"
load "stdlib.ring"
Line 4,101 ⟶ 6,256:
next
next
</syntaxhighlight>
</lang>
Output:
 
Line 4,107 ⟶ 6,262:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class FlipBoard
def initialize(size)
raise ArgumentError.new("Invalid board size: #{size}") if size < 2
Line 4,210 ⟶ 6,365:
rescue => e
puts e.message
end</langsyntaxhighlight>
 
Sample game:
Line 4,247 ⟶ 6,402:
2 0 1 1
3 0 1 0
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
// For random generation
extern crate rand;
 
// For fmt::Display
use std::fmt;
// For I/O (stdin, stdout, etc)
use std::io::prelude::*;
 
use rand::Rng;
 
/// A simple struct for a board
struct Board {
/// The cells of the board
cells: Vec<bool>,
/// The size of the board
size: usize,
}
 
// Functions for the Board struct
impl Board {
/// Generate a new, empty board, of size >= 1
///
/// Returns a Board in the "off" state, where all cells are 0.
/// If a size of 0 is given, a Board of size 1 will be created instead.
/// A mutable board is required for using Board::fliprow and Board::flipcol functions.
///
/// ```
/// let mut board: Board = Board::new(3);
/// ```
fn new(size: usize) -> Board {
// Ensure we make a board with a non-zero size
if size > 0 {
Board {
cells: vec![false; size * size],
size,
}
} else {
Board::new(1)
}
}
 
/// Flip the specified row
///
/// Returns true if the row is within the size, false otherwise.
///
/// ```
/// let mut board: Board = Board::new(3);
/// board.fliprow(1);
/// ```
fn fliprow(&mut self, row: usize) -> bool {
// Check constraints
if row > self.size {
return false;
}
// Starting position in the vector
let start = row * self.size;
// Loop through the vector row
for i in start..start + self.size {
self.cells[i] = !self.cells[i];
}
true
}
 
/// Flip the specified column
///
/// Returns true if the column is within the size, false otherwise.
///
/// ```
/// let mut board: Board = Board::new(3);
/// board.flipcol(0);
/// ```
fn flipcol(&mut self, col: usize) -> bool {
// Check constraints
if col > self.size {
return false;
}
// Loop through the vector column
for i in 0..self.size {
self.cells[col + i * self.size] = !self.cells[col + i * self.size];
}
true
}
 
/// Generate a random board
///
/// Returns a Board in a random state.
/// If a size of 0 is given, a Board of size 1 will be created instead.
///
/// ```
/// let target: Board = Board::random(3);
/// ```
fn random<R: Rng>(rng: &mut R, size: usize) -> Board {
// Ensure we make a board with a non-zero size
if size == 0 {
return Board::random(rng, 1);
}
 
// Make a vector of the board size with random bits
let cells = (0..size * size)
.map(|_| rng.gen::<bool>())
.collect::<Vec<_>>();
// Return the random board
Board { cells, size }
}
}
 
impl PartialEq for Board {
fn eq(&self, rhs: &Board) -> bool {
self.cells == rhs.cells
}
}
 
// Implement the Display format, used with `print!("{}", &board);`
impl fmt::Display for Board {
// Example output:
// 0 1 2
// 0 0 1 0
// 1 1 0 0
// 2 0 1 1
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Get the string width of the size of the board
let width = (self.size - 1).to_string().len();
// Write the initial spaces (upper left)
write!(f, "{space: >0$}", width, space = " ")?;
// Write the column numbers
for i in 0..self.size {
write!(f, " {offset:>0$}", width, offset = i)?;
}
// Newline for rows
writeln!(f)?;
// Loop through the rows
for row in 0..self.size {
// Write the row number
write!(f, "{row:>0$}", width, row = row)?;
// Loop through the columns
for col in 0..self.size {
// Get the value of the cell as 1 or 0
let p = self.cells[row * self.size + col] as usize;
// Write the column value
write!(f, " {col:>0$}", width, col = p)?;
}
// Newline for next row
writeln!(f)?;
}
// Return Formatter result
Ok(())
}
}
 
fn main() {
let mut rng = rand::thread_rng();
 
// The board size
let size: usize = 3;
// The target board
let target: Board = Board::random(&mut rng, size);
// The user board
let mut board: Board = Board::new(size);
// How many moves taken
let mut moves: u32 = 0;
// Loop until win or quit
'mainloop: loop {
// User input
let mut input: String;
// Write the boards
println!("Target:\n{}\nBoard:\n{}", &target, &board);
// User input loop
'userinput: loop {
// Prompt
print!("\nFlip? [q|[r|c]#] ");
// Flush stdout to write the previous print, if we can't then exit
match std::io::stdout().flush() {
Ok(_) => {}
Err(e) => {
println!("Error: cannot flush stdout: {}", e);
break 'mainloop;
}
};
// Reset input for each loop
input = String::new();
// Read user input
match std::io::stdin().read_line(&mut input) {
Ok(_) => {
input = input.trim().to_string();
// Get the first character
let rc: char = match input.chars().next() {
Some(c) => c,
None => {
println!("Error: No input");
continue 'userinput;
}
};
// Make sure input is r, c, or q
if rc != 'r' && rc != 'c' && rc != 'q' {
println!("Error: '{}': Must use 'r'ow or 'c'olumn or 'q'uit", rc);
continue 'userinput;
}
// If input is q, exit game
if rc == 'q' {
println!("Thanks for playing!");
break 'mainloop;
}
// If input is r or c, get the number after
let n: usize = match input[1..].to_string().parse() {
Ok(x) => {
// If we're within bounds, return the parsed number
if x < size {
x
} else {
println!(
"Error: Must specify a row or column within size({})",
size
);
continue 'userinput;
}
}
Err(_) => {
println!(
"Error: '{}': Unable to parse row or column number",
input[1..].to_string()
);
continue 'userinput;
}
};
// Flip the row or column specified
match rc {
'r' => board.fliprow(n),
'c' => board.flipcol(n),
_ => {
// We want to panic here because should NEVER
// have anything other than 'r' or 'c' here
panic!("How did you end up here?");
}
};
// Increment moves
moves += 1;
println!("Moves taken: {}", moves);
break 'userinput;
}
Err(e) => {
println!("Error reading input: {}", e);
break 'mainloop;
}
}
} // 'userinput
if board == target {
println!("You win!");
break;
}
} // 'mainloop
}
</syntaxhighlight>
{{out}}
<pre>
Target:
0 1 2
0 1 0 0
1 0 0 0
2 0 1 1
 
Board:
0 1 2
0 0 0 0
1 0 0 0
2 0 0 0
 
 
Flip? [q|[r|c]#] r1
Moves taken: 1
Target:
0 1 2
0 1 0 0
1 0 0 0
2 0 1 1
 
Board:
0 1 2
0 0 0 0
1 1 1 1
2 0 0 0
</pre>
 
Line 4,254 ⟶ 6,693:
{{libheader|Scala GUI Game}}
{{works with|Scala|2.13}}
<langsyntaxhighlight Scalalang="scala">import java.awt.{BorderLayout, Color, Dimension, Font, Graphics, Graphics2D, Rectangle, RenderingHints}
import java.awt.event.{MouseAdapter, MouseEvent}
 
Line 4,361 ⟶ 6,800:
}
 
}</langsyntaxhighlight>
{{output?|Scala}}
 
=={{header|Swift}}==
{{works with|Swift 2.0}}
<langsyntaxhighlight lang="swift">import Foundation
 
struct Board: Equatable, CustomStringConvertible {
Line 4,500 ⟶ 6,939:
let game = FlippingGame(boardSize: 3)
repeat { } while playGame(game) == "y"
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 4,530 ⟶ 6,969:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create Flip {
Line 4,622 ⟶ 7,061:
Flip create flip 3
flip play
</syntaxhighlight>
</lang>
{{out|Example game}}
<pre>
Line 4,651 ⟶ 7,090:
 
You win! (You took 2 moves.)
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-ioutil}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "random" for Random
import "./ioutil" for Input
import "./str" for Str
 
var rand = Random.new()
var target = List.filled(3, null)
var board = List.filled(3, null)
for (i in 0..2) {
target[i] = List.filled(3, 0)
board[i] = List.filled(3, 0)
for (j in 0..2) target[i][j] = rand.int(2)
}
 
var flipRow = Fn.new { |r|
for (c in 0..2) board[r][c] = (board[r][c] == 0) ? 1 : 0
}
 
var flipCol = Fn.new { |c|
for (r in 0..2) board[r][c] = (board[r][c] == 0) ? 1 : 0
}
 
/* starting from the target we make 9 random row or column flips */
var initBoard = Fn.new {
for (i in 0..2) {
for (j in 0..2) board[i][j] = target[i][j]
}
for (i in 1..9) {
var rc = rand.int(2)
if (rc == 0) {
flipRow.call(rand.int(3))
} else {
flipCol.call(rand.int(3))
}
}
}
 
var printBoard = Fn.new { |label, isTarget|
var a = (isTarget) ? target : board
System.print("%(label):")
System.print(" | a b c")
System.print("---------")
for (r in 0..2) {
System.write("%(r + 1) |")
for (c in 0..2) System.write(" %(a[r][c])")
System.print()
}
System.print()
}
 
var gameOver = Fn.new {
for (r in 0..2) {
for (c in 0..2) if (board[r][c] != target[r][c]) return false
}
return true
}
 
// initialize board and ensure it differs from the target i.e. game not already over!
while (true) {
initBoard.call()
if (!gameOver.call()) break
}
 
printBoard.call("TARGET", true)
printBoard.call("OPENING BOARD", false)
var flips = 0
 
while (true) {
var isRow = true
var n = -1
var prompt = "Enter row number or column letter to be flipped: "
var ch = Str.lower(Input.option(prompt, "123abcABC"))
if (ch == "1" || ch == "2" || ch == "3") {
n = ch.bytes[0] - 49
} else {
isRow = false
n = ch.bytes[0] - 97
}
flips = flips + 1
if (isRow) flipRow.call(n) else flipCol.call(n)
var plural = (flips == 1) ? "" : "S"
printBoard.call("\nBOARD AFTER %(flips) FLIP%(plural)", false)
if (gameOver.call()) break
}
 
var plural = (flips == 1) ? "" : "s"
System.print("You've succeeded in %(flips) flip%(plural)")</syntaxhighlight>
 
{{out}}
Sample (lucky!) game:
<pre>
TARGET:
| a b c
---------
1 | 1 1 0
2 | 1 1 1
3 | 0 0 0
 
OPENING BOARD:
| a b c
---------
1 | 0 0 1
2 | 1 1 1
3 | 0 0 0
 
Enter row number or column letter to be flipped: 1
 
BOARD AFTER 1 FLIP:
| a b c
---------
1 | 1 1 0
2 | 1 1 1
3 | 0 0 0
 
You've succeeded in 1 flip
</pre>
Anonymous user