Task: Flipping bits game







Python: 

from random import randrange
from copy import deepcopy
from string import ascii_lowercase


try:    
    input = raw_input
except:
    pass

N = 3   

board  = [[0]* N for i in range(N)]

def setbits(board, count=1):
    for i in range(count):
        board[randrange(N)][randrange(N)] ^= 1

def shuffle(board, count=1):
    for i in range(count):
        if randrange(0, 2):
            fliprow(randrange(N))
        else:
            flipcol(randrange(N))


def pr(board, comment=''):
    print(str(comment))
    print('     ' + ' '.join(ascii_lowercase[i] for i in range(N)))
    print('  ' + '\n  '.join(' '.join(['%2s' % j] + [str(i) for i in line])
                             for j, line in enumerate(board, 1)))

def init(board):
    setbits(board, count=randrange(N)+1)
    target = deepcopy(board)
    while board == target:
        shuffle(board, count=2 * N)
    prompt = '  X, T, or 1-%i / %s-%s to flip: ' % (N, ascii_lowercase[0], 
                                                    ascii_lowercase[N-1])
    return target, prompt

def fliprow(i):
    board[i-1][:] = [x ^ 1 for x in board[i-1] ]
    
def flipcol(i):
    for row in board:
        row[i] ^= 1

if __name__ == '__main__':
    print(__doc__ % (N, N))
    target, prompt = init(board)
    pr(target, 'Target configuration is:')
    print('')
    turns = 0
    while board != target:
        turns += 1
        pr(board, '%i:' % turns)
        ans = input(prompt).strip()
        if (len(ans) == 1 
            and ans in ascii_lowercase and ascii_lowercase.index(ans) < N):
            flipcol(ascii_lowercase.index(ans))
        elif ans and all(ch in '0123456789' for ch in ans) and 1 <= int(ans) <= N:
            fliprow(int(ans))
        elif ans == 'T':
            pr(target, 'Target configuration is:')
            turns -= 1
        elif ans == 'X':
            break
        else:
            print("  I don't understand %r... Try again. "
                  "(X to exit or T to show target)\n" % ans[:9])
            turns -= 1
    else:
        print('\nWell done!\nBye.')





Ada: with Ada.Text_IO, Ada.Command_Line, Ada.Numerics.Discrete_Random;

procedure Flip_Bits is
   
   subtype Letter is Character range 'a' .. 'z';
   
   Last_Col: constant letter := Ada.Command_Line.Argument(1)(1);
   Last_Row: constant Positive := Positive'Value(Ada.Command_Line.Argument(2));
   
   package Boolean_Rand is new Ada.Numerics.Discrete_Random(Boolean);
   Gen: Boolean_Rand.Generator;
   
   type Matrix is array
     (Letter range 'a' .. Last_Col, Positive range 1 .. Last_Row) of Boolean;
   
   function Rand_Mat return Matrix is
      M: Matrix;
   begin
      for I in M'Range(1) loop
	 for J in M'Range(2) loop
	    M(I,J) := Boolean_Rand.Random(Gen);
	 end loop;
      end loop;
      return M;
   end Rand_Mat;
   
   function Rand_Mat(Start: Matrix) return Matrix is
      M: Matrix := Start;
   begin
      for I in M'Range(1) loop
	 if  Boolean_Rand.Random(Gen) then
	    for J in M'Range(2) loop
	       M(I,J) := not M(I, J);
	    end loop;
	 end if;
      end loop;
      for I in M'Range(2) loop
	 if  Boolean_Rand.Random(Gen) then
	    for J in M'Range(1) loop
	       M(J,I) := not M(J, I);
	    end loop;
	 end if;
      end loop;
      return M;
   end Rand_Mat;
   
   procedure Print(Message: String; Mat: Matrix) is
      package NIO is new Ada.Text_IO.Integer_IO(Natural);
   begin
      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line(Message);
      Ada.Text_IO.Put("   ");
      for Ch in Matrix'Range(1) loop
	 Ada.Text_IO.Put(" " & Ch);
      end loop;
      Ada.Text_IO.New_Line;
      for I in Matrix'Range(2) loop
	 NIO.Put(I, Width => 3);
	 for Ch in Matrix'Range(1) loop
	    Ada.Text_IO.Put(if Mat(Ch, I) then " 1" else " 0");
	 end loop;
         Ada.Text_IO.New_Line;
      end loop;
   end Print;

   Current, Target: Matrix;
   Moves: Natural := 0;
       
begin
   
   Boolean_Rand.Reset(Gen);
   Target := Rand_Mat;
   loop
      Current := Rand_Mat(Target);
      exit when Current /= Target;
   end loop;
   Print("Target:", Target);
   
   
   while Current /= Target loop
     Moves := Moves + 1;
     Print("Current move #" & Natural'Image(Moves), Current);
      Ada.Text_IO.Put_Line("Flip row 1 .." & Positive'Image(Last_Row) &
			     " or column 'a' .. '" & Last_Col & "'");
      declare
	 S: String := Ada.Text_IO.Get_Line;
	 function Let(S: String) return Character is (S(S'First));
	 function Val(Str: String) return Positive is (Positive'Value(Str));
      begin
	 if Let(S) in 'a' .. Last_Col then
	    for I in Current'Range(2) loop
	       Current(Let(S), I) := not Current(Let(S), I);
	    end loop;
	 else 
	    for I in Current'Range(1) loop
	       Current(I, Val(S)) := not Current(I, Val(S));
	    end loop;
	 end if;
      end;
   end loop;
   
   
   Ada.Text_IO.Put_Line("Done after" & Natural'Image(Moves) & " Moves.");
end Flip_Bits;