Flipping bits game: Difference between revisions

Added Forth entry.
imported>CyD
(Added Forth entry.)
 
(16 intermediate revisions by 12 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}}==
Line 27 ⟶ 117:
This program runs under CP/M and takes the board size from the command line.
 
<langsyntaxhighlight lang="8080asm"> ;;; Flip the Bits game, CP/M version.
;;; CP/M zero page locations
cmdln: equ 80h
Line 407 ⟶ 497:
xabcdat: ds 4 ; RNG state
board: equ $
goal: equ board + 64 ; Max. 8*8 board</langsyntaxhighlight>
 
{{out}}
Line 440 ⟶ 530:
 
This program runs under MS-DOS and takes the board size from the command line.
<langsyntaxhighlight lang="asm"> bits 16
cpu 8086
;;; MS-DOS PSP locations
Line 742 ⟶ 832:
xabcdat: resb 4 ; Four byte RNG state
board: resb 64 ; 8*8 board
goal: resb 64 ; 8*8 goal</langsyntaxhighlight>
 
{{out}}
Line 774 ⟶ 864:
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 881 ⟶ 1,114:
-- summarize the outcome
Ada.Text_IO.Put_Line("Done after" & Natural'Image(Moves) & " Moves.");
end Flip_Bits;</langsyntaxhighlight>
 
{{out}}
Line 915 ⟶ 1,148:
{{works with|GNU APL}}
 
<langsyntaxhighlight APLlang="apl">#!/usr/local/bin/apl -s --
 
∇r←b FlipRow ix ⍝ Flip a row
Line 982 ⟶ 1,215:
Game
)OFF</langsyntaxhighlight>
 
{{out}}
Line 1,017 ⟶ 1,250:
{{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 1,099 ⟶ 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 1,218 ⟶ 1,654:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,253 ⟶ 1,689:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <time.h>
#include <iostream>
Line 1,346 ⟶ 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 1,368 ⟶ 1,804:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn cols [board]
(mapv vec (apply map list board)))
 
Line 1,432 ⟶ 1,868:
(println "Target")
(print-board target-board)
(play-game target-board (play-rand target-board 3) 0))))</langsyntaxhighlight>
 
{{out}}
Line 1,459 ⟶ 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 1,528 ⟶ 1,964:
 
"\nWell done!".writeln;
}</langsyntaxhighlight>
{{out}}
<pre>T prints the target, and Q exits.
Line 1,557 ⟶ 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 1,623 ⟶ 2,059:
end
 
Flip_game.play(3)</langsyntaxhighlight>
 
{{out}}
Line 1,659 ⟶ 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,861 ⟶ 2,634:
end do
end subroutine
</syntaxhighlight>
</lang>
 
Example:
Line 1,945 ⟶ 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 2,068 ⟶ 3,055:
}
return o
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,118 ⟶ 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 2,232 ⟶ 3,219:
tryAgain = do
putStrLn ": Invalid row or column."
turns goal current moves</langsyntaxhighlight>
{{Out}}
<pre>Select a board size (1 - 9).
Line 2,273 ⟶ 3,260:
Using J's command line as the game ui:
 
<langsyntaxhighlight Jlang="j">start=:3 :0
Moves=:0
N=:i.y
Line 2,293 ⟶ 3,280:
Board;End
end.
)</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight Jlang="j"> start 3
┌─────┬─────┐
│1 1 1│1 0 1│
Line 2,312 ⟶ 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 2,319 ⟶ 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 2,473 ⟶ 3,460:
});
}
}</langsyntaxhighlight>
<pre>The target
[0, 1, 0]
Line 2,490 ⟶ 3,477:
 
=={{header|JavaScript}}==
<langsyntaxhighlight JavaScriptlang="javascript">function numOfRows(board) { return board.length; }
function numOfCols(board) { return board[0].length; }
function boardToString(board) {
Line 2,585 ⟶ 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 2,634 ⟶ 3,621:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">module FlippingBitsGame
 
using Printf, Random
Line 2,735 ⟶ 3,722:
 
FlippingBitsGame.play()
</langsyntaxhighlight>{{output}}
<pre>Insert the size of the matrix (nrow [> 1] *space* ncol [> 1]):3 3
 
Line 2,781 ⟶ 3,768:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.util.Random
Line 2,872 ⟶ 3,859:
val plural = if (flips == 1) "" else "s"
println("You've succeeded in $flips flip$plural")
}</langsyntaxhighlight>
 
{{out}}
Line 2,922 ⟶ 3,909:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">
target, board, moves, W, H = {}, {}, 0, 3, 3
 
Line 3,018 ⟶ 4,005:
math.randomseed( os.time() )
play()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,053 ⟶ 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 3,159 ⟶ 4,146:
end module:
 
FlippingBits(3);</langsyntaxhighlight>
{{out}}
<pre>
Line 3,186 ⟶ 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 3,275 ⟶ 4,320:
end
fprintf('\n')
end</langsyntaxhighlight>
{{out}}
Normal play and winning:
Line 3,397 ⟶ 4,442:
 
=={{header|MiniScript}}==
<langsyntaxhighlight MiniScriptlang="miniscript">// Flipping Bits game.
// Transform a start grid to an end grid by flipping rows or columns.
 
Line 3,461 ⟶ 4,506:
flipAny(inp)
end while
print "You did it!"</langsyntaxhighlight>
 
{{out}}
Line 3,488 ⟶ 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 3,561 ⟶ 4,771:
if not !Sys.interactive then
(Random.self_init ();
play ())</langsyntaxhighlight>
 
{{out}}
Line 3,629 ⟶ 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 3,654 ⟶ 4,864:
{
for(@rows, @cols) {
$start ^.= $_ if int rand 2;
}
redo if $start eq $goal;
Line 3,694 ⟶ 4,904:
$did_one = 1;
if( /\d/ ) {
$start ^.= $rows[$_-1];
} else {
$_ = ord(lc) - ord('a');
$start ^.= $cols[$_];
}
++$moves_so_far;
Line 3,704 ⟶ 4,914:
}
}
print "You won after $moves_so_far moves.\n";</langsyntaxhighlight>
{{out}}
<pre>$ perl FlippingBitsGame.pl 3
Line 3,729 ⟶ 4,939:
 
=={{header|Phix}}==
<langsyntaxhighlight Phixlang="phix">integer w, h
 
string board, target
Line 3,883 ⟶ 5,093:
end while
end procedure
main()</langsyntaxhighlight>
{{out}}
<pre>
Line 3,956 ⟶ 5,166:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">(subscriptrange, stringrange, stringsize):
flip: procedure options (main);
declare n fixed binary;
Line 4,004 ⟶ 5,214:
end;
 
end flip;</langsyntaxhighlight>
{{out}}
<pre>
Line 4,036 ⟶ 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 4,120 ⟶ 5,330:
turns -= 1
else:
print('\nWell done!\nBye.')</langsyntaxhighlight>
 
{{out}}
Line 4,208 ⟶ 5,418:
 
=={{header|QB64}}==
<syntaxhighlight lang="text">
RANDOMIZE TIMER
DIM SHARED cellsPerSide, legalMoves$, startB$, currentB$, targetB$, moveCount
Line 4,388 ⟶ 5,598:
getKey$ = k$
END FUNCTION
</syntaxhighlight>
</lang>
'''Output:'''
<syntaxhighlight lang="text">
Flipping Bits Game, now with AI! b+ 2017-12-18
 
Line 4,482 ⟶ 5,692:
 
--------------------------------------------------------------------------------
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
<syntaxhighlight lang="text">#lang racket
(define (flip-row! pzzl r)
(define N (integer-sqrt (bytes-length pzzl)))
Line 4,555 ⟶ 5,765:
[else (printf "unrecognised character in input: ~s~%" else)
(turn n)])]))
(turn 0))</langsyntaxhighlight>
 
{{out}}
Line 4,582 ⟶ 5,792:
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" perl6line>sub MAIN ($square = 4) {
say "{$square}? Seriously?" and exit if $square < 1 or $square > 26;
my %bits = map { $_ => %( map { $_ => 0 }, ('A' .. *)[^ $square] ) },
Line 4,635 ⟶ 5,845:
@keys.push: | keys %hash{'1'};
flip $_, %hash for @keys.pick( @keys/2 );
}</langsyntaxhighlight>
A sample 3 x 3 game might look like this:
<pre>Goal
Line 4,693 ⟶ 5,903:
Hurray! You solved it in 3 turns.</pre>
=={{header|Red}}==
<syntaxhighlight lang="rebol">
<lang Rebol>
Red []
random/seed now/time/precise ;; start random generator
Line 4,736 ⟶ 5,946:
flip inp
] ;; 42 lines :- )
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,787 ⟶ 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 4,855 ⟶ 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 4,936 ⟶ 6,146:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
load "guilib.ring"
load "stdlib.ring"
Line 5,046 ⟶ 6,256:
next
next
</syntaxhighlight>
</lang>
Output:
 
Line 5,052 ⟶ 6,262:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class FlipBoard
def initialize(size)
raise ArgumentError.new("Invalid board size: #{size}") if size < 2
Line 5,155 ⟶ 6,365:
rescue => e
puts e.message
end</langsyntaxhighlight>
 
Sample game:
Line 5,192 ⟶ 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 5,199 ⟶ 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 5,306 ⟶ 6,800:
}
 
}</langsyntaxhighlight>
{{output?|Scala}}
 
=={{header|Swift}}==
{{works with|Swift 2.0}}
<langsyntaxhighlight lang="swift">import Foundation
 
struct Board: Equatable, CustomStringConvertible {
Line 5,445 ⟶ 6,939:
let game = FlippingGame(boardSize: 3)
repeat { } while playGame(game) == "y"
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 5,475 ⟶ 6,969:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create Flip {
Line 5,567 ⟶ 7,061:
Flip create flip 3
flip play
</syntaxhighlight>
</lang>
{{out|Example game}}
<pre>
Line 5,596 ⟶ 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