Flipping bits game: Difference between revisions

Added Forth entry.
(→‎{{header|Nim}}: fix OCaml header issue)
imported>CyD
(Added Forth entry.)
 
(10 intermediate revisions by 8 users not shown)
Line 22:
Show an example of a short game here, on this page, for a   '''3×3'''   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}}==
<langsyntaxhighlight BASIClang="basic">10 DEFINT A-Z
20 PRINT "*** FLIP THE BITS ***"
30 INPUT "Board size";S
Line 1,144 ⟶ 1,377:
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</langsyntaxhighlight>
{{out}}
<pre>*** FLIP THE BITS ***
Line 1,175 ⟶ 1,408:
 
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,293 ⟶ 1,654:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,328 ⟶ 1,689:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <time.h>
#include <iostream>
Line 1,421 ⟶ 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,443 ⟶ 1,804:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(defn cols [board]
(mapv vec (apply map list board)))
 
Line 1,507 ⟶ 1,868:
(println "Target")
(print-board target-board)
(play-game target-board (play-rand target-board 3) 0))))</langsyntaxhighlight>
 
{{out}}
Line 1,534 ⟶ 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,603 ⟶ 1,964:
 
"\nWell done!".writeln;
}</langsyntaxhighlight>
{{out}}
<pre>T prints the target, and Q exits.
Line 1,632 ⟶ 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,698 ⟶ 2,059:
end
 
Flip_game.play(3)</langsyntaxhighlight>
 
{{out}}
Line 1,737 ⟶ 2,098:
=={{header|FOCAL}}==
 
<langsyntaxhighlight FOCALlang="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
Line 1,775 ⟶ 2,136:
05.60 I (A-2)5.7;T "C";R
05.70 I (A-1)5.8;T "B";R
05.80 T "A"</langsyntaxhighlight>
 
{{out}}
Line 1,813 ⟶ 2,174:
 
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 2,015 ⟶ 2,634:
end do
end subroutine
</syntaxhighlight>
</lang>
 
Example:
Line 2,099 ⟶ 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,222 ⟶ 3,055:
}
return o
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,272 ⟶ 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,386 ⟶ 3,219:
tryAgain = do
putStrLn ": Invalid row or column."
turns goal current moves</langsyntaxhighlight>
{{Out}}
<pre>Select a board size (1 - 9).
Line 2,427 ⟶ 3,260:
Using J's command line as the game ui:
 
<langsyntaxhighlight Jlang="j">start=:3 :0
Moves=:0
N=:i.y
Line 2,447 ⟶ 3,280:
Board;End
end.
)</langsyntaxhighlight>
 
Example:
 
<langsyntaxhighlight Jlang="j"> start 3
┌─────┬─────┐
│1 1 1│1 0 1│
Line 2,466 ⟶ 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,473 ⟶ 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,627 ⟶ 3,460:
});
}
}</langsyntaxhighlight>
<pre>The target
[0, 1, 0]
Line 2,644 ⟶ 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,739 ⟶ 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,788 ⟶ 3,621:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">module FlippingBitsGame
 
using Printf, Random
Line 2,889 ⟶ 3,722:
 
FlippingBitsGame.play()
</langsyntaxhighlight>{{output}}
<pre>Insert the size of the matrix (nrow [> 1] *space* ncol [> 1]):3 3
 
Line 2,935 ⟶ 3,768:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.util.Random
Line 3,026 ⟶ 3,859:
val plural = if (flips == 1) "" else "s"
println("You've succeeded in $flips flip$plural")
}</langsyntaxhighlight>
 
{{out}}
Line 3,076 ⟶ 3,909:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">
target, board, moves, W, H = {}, {}, 0, 3, 3
 
Line 3,172 ⟶ 4,005:
math.randomseed( os.time() )
play()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,207 ⟶ 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,313 ⟶ 4,146:
end module:
 
FlippingBits(3);</langsyntaxhighlight>
{{out}}
<pre>
Line 3,340 ⟶ 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,429 ⟶ 4,320:
end
fprintf('\n')
end</langsyntaxhighlight>
{{out}}
Normal play and winning:
Line 3,551 ⟶ 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,615 ⟶ 4,506:
flipAny(inp)
end while
print "You did it!"</langsyntaxhighlight>
 
{{out}}
Line 3,647 ⟶ 4,538:
Translation of Kotlin program with some modifications.
 
<langsyntaxhighlight Nimlang="nim">import random, strformat, strutils
 
type
Line 3,740 ⟶ 4,631:
 
let plural = if flips == 1: "" else: "s"
echo &"You’ve succeeded in {flips} flip{plural}"</langsyntaxhighlight>
 
{{out}}
Line 3,809 ⟶ 4,700:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">module FlipGame =
struct
type t = bool array array
Line 3,880 ⟶ 4,771:
if not !Sys.interactive then
(Random.self_init ();
play ())</langsyntaxhighlight>
 
{{out}}
Line 3,948 ⟶ 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,973 ⟶ 4,864:
{
for(@rows, @cols) {
$start ^.= $_ if int rand 2;
}
redo if $start eq $goal;
Line 4,013 ⟶ 4,904:
$did_one = 1;
if( /\d/ ) {
$start ^.= $rows[$_-1];
} else {
$_ = ord(lc) - ord('a');
$start ^.= $cols[$_];
}
++$moves_so_far;
Line 4,023 ⟶ 4,914:
}
}
print "You won after $moves_so_far moves.\n";</langsyntaxhighlight>
{{out}}
<pre>$ perl FlippingBitsGame.pl 3
Line 4,048 ⟶ 4,939:
 
=={{header|Phix}}==
<langsyntaxhighlight Phixlang="phix">integer w, h
 
string board, target
Line 4,202 ⟶ 5,093:
end while
end procedure
main()</langsyntaxhighlight>
{{out}}
<pre>
Line 4,275 ⟶ 5,166:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">(subscriptrange, stringrange, stringsize):
flip: procedure options (main);
declare n fixed binary;
Line 4,323 ⟶ 5,214:
end;
 
end flip;</langsyntaxhighlight>
{{out}}
<pre>
Line 4,355 ⟶ 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,439 ⟶ 5,330:
turns -= 1
else:
print('\nWell done!\nBye.')</langsyntaxhighlight>
 
{{out}}
Line 4,527 ⟶ 5,418:
 
=={{header|QB64}}==
<syntaxhighlight lang="text">
RANDOMIZE TIMER
DIM SHARED cellsPerSide, legalMoves$, startB$, currentB$, targetB$, moveCount
Line 4,707 ⟶ 5,598:
getKey$ = k$
END FUNCTION
</syntaxhighlight>
</lang>
'''Output:'''
<syntaxhighlight lang="text">
Flipping Bits Game, now with AI! b+ 2017-12-18
 
Line 4,801 ⟶ 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,874 ⟶ 5,765:
[else (printf "unrecognised character in input: ~s~%" else)
(turn n)])]))
(turn 0))</langsyntaxhighlight>
 
{{out}}
Line 4,901 ⟶ 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,954 ⟶ 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 5,012 ⟶ 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 5,055 ⟶ 5,946:
flip inp
] ;; 42 lines :- )
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,106 ⟶ 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 5,174 ⟶ 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 5,255 ⟶ 6,146:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
load "guilib.ring"
load "stdlib.ring"
Line 5,365 ⟶ 6,256:
next
next
</syntaxhighlight>
</lang>
Output:
 
Line 5,371 ⟶ 6,262:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class FlipBoard
def initialize(size)
raise ArgumentError.new("Invalid board size: #{size}") if size < 2
Line 5,474 ⟶ 6,365:
rescue => e
puts e.message
end</langsyntaxhighlight>
 
Sample game:
Line 5,514 ⟶ 6,405:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">
// For random generation
extern crate rand;
Line 5,766 ⟶ 6,657:
} // 'mainloop
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,802 ⟶ 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,909 ⟶ 6,800:
}
 
}</langsyntaxhighlight>
{{output?|Scala}}
 
=={{header|Swift}}==
{{works with|Swift 2.0}}
<langsyntaxhighlight lang="swift">import Foundation
 
struct Board: Equatable, CustomStringConvertible {
Line 6,048 ⟶ 6,939:
let game = FlippingGame(boardSize: 3)
repeat { } while playGame(game) == "y"
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 6,078 ⟶ 6,969:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create Flip {
Line 6,170 ⟶ 7,061:
Flip create flip 3
flip play
</syntaxhighlight>
</lang>
{{out|Example game}}
<pre>
Line 6,199 ⟶ 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