Lights Off Solver



Hi folks,

I've written a program which solves lights off game for every position when I got frustrated not being able to solve some simple positions. here's the code, feel free to use, change, share, etc:

/*
 * Copyright (C) Perham 2011 <perham x gmail com>
 *
 * LightsOffSolver is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * LightsOffSolver is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <vector>
#include <iostream>
#include <fstream>



using namespace std;

int
negative (int input_board, int square)
{
  return input_board ^ (1 << square);
}

int
setbit (int input_board, int square, int bit)
{
  if ((input_board >> square) % 2 == bit)
    return input_board;
  else
    return negative (input_board, square);
}

int
copybit (int input_board, int in_pos, int output_board, int out_pos)
{
  return setbit (output_board, out_pos, (input_board >> in_pos) % 2);
}

int
rotate_move (int move, int degree)
{
  if (degree == 90)
    return 20 - ((move % 5) * 5) + (move / 5);

  else if (degree == 180)
    return (24 - move);

  else if (degree == 270)
    return 4 + ((move % 5) * 5) - (move / 5);

  return -1;

}

int
rotate_board (int input_board, int degree)
{
  int output_board = 0, i;

  for (i = 0; i < 25; i++)
    output_board =
      copybit (input_board, i, output_board, rotate_move (i, degree));

  return output_board;
}



int
generate (int input_board, int move)
{
  if (move > 5 && move < 19 && move % 5 != 0 && move % 5 != 4)
    return
      negative (negative
        (negative
         (negative (negative (input_board, move), move + 5),
          move - 5), move + 1), move - 1);
  if (move > 0 && move < 4)
    return
      negative (negative
        (negative (negative (input_board, move), move + 5), move - 1),
        move + 1);
  if (move > 20 && move < 24)
    return
      negative (negative
        (negative (negative (input_board, move), move - 5), move - 1),
        move + 1);
  if (move == 5 || move == 10 || move == 15)
    return
      negative (negative
        (negative (negative (input_board, move), move + 5), move + 1),
        move - 5);
  if (move == 9 || move == 14 || move == 19)
    return
      negative (negative
        (negative (negative (input_board, move), move + 5), move - 1),
        move - 5);
  if (move == 0)
    return negative (negative (negative (input_board, 0), 1), 6);
  if (move == 4)
    return negative (negative (negative (input_board, 4), 3), 9);
  if (move == 20)
    return negative (negative (negative (input_board, 20), 21), 15);
  if (move == 24)
    return negative (negative (negative (input_board, 24), 19), 23);
}

void
print (int input_board)
{
  int tmp, i;
  for (i = 0; i < 5; i++)
    {
      tmp = (input_board >> (5 * i)) % 32;
      cout << "\n" << (int) tmp % 2 << (int) (tmp % 4) / 2 << (int) (tmp %
                                     8) /
    4 << (int) (tmp % 16) / 8 << (int) tmp / 16;
    }

  cout << "\n";
}

class queue
{
public:
  vector < int >q;


  void add (int n)
  {
    q.push_back (n);
  }

  int remove (void)
  {

    int tmp;
    tmp = q.at (0);
    q.erase (q.begin ());
    return tmp;


  }

  int check (int n)
  {
    int i;
    for (i = 0; i < q.size (); i++)
      if (q.at (i) == n)
    return 1;
    return 0;
  }

  int size (void)
  {
    return q.size ();
  }

  queue ()
  {
    q.reserve (3000000);
    q.assign (1, 0);
  }

};


int
main ()
{
  cout << "\ninitializing...";
  cout.flush ();

  int i, j, s, flag =
    0, tmp1, tmp2, tmp1r1, tmp1r2, tmp1r3, tmp2r1, tmp2r2, tmp2r3;


  vector < char >mark (33554432, 0);
  fstream filestr;
  vector < vector < char > >tree;
  tree.resize (33554432);



  j = 0;

  mark[0] = 1;
  queue Q;
  cout << " done.\n";
  cout.flush ();
  while (s)
    {
     
      tmp2 = Q.remove ();
      cout << "\rqueue: " << s <<"    ";
      tmp2r1 = rotate_board (tmp2, 90);
      tmp2r2 = rotate_board (tmp2, 180);
      tmp2r3 = rotate_board (tmp2r2, 90);

      for (i = 0; i < 25; i++)
    {
      tmp1 = generate (tmp2, i);
      tmp1r1 = rotate_board (tmp1, 90);
      tmp1r2 = rotate_board (tmp1, 180);
      tmp1r3 = rotate_board (tmp1r2, 90);

      if (mark.at (tmp1) == 0)
        {
          Q.add (tmp1);
          mark[tmp1] = 1;
          tree[tmp1].assign (tree[tmp2].begin (), tree[tmp2].end ());
          tree[tmp1].push_back (i);

          if (!(tmp1r1 == tmp1 || tmp1r2 == tmp1 || tmp1r3 == tmp1))
        {
          mark[tmp1r1] = 1;
          mark[tmp1r2] = 1;
          mark[tmp1r3] = 1;


          tree[tmp1r1].assign (tree[tmp2r1].begin (),
                       tree[tmp2r1].end ());
          tree[tmp1r1].push_back (rotate_move (i, 90));

          tree[tmp1r2].assign (tree[tmp2r2].begin (),
                       tree[tmp2r2].end ());
          tree[tmp1r2].push_back (rotate_move (i, 180));

          tree[tmp1r3].assign (tree[tmp2r3].begin (),
                       tree[tmp2r3].end ());
          tree[tmp1r3].push_back (rotate_move (i, 270));
        }

        }

    }

s = Q.size ();   
}

  cout << "\nwriting to output...\n";
  cout.flush ();
  filestr.open ("output.txt", fstream::out);

  for (i = 0; i < 33554432; i++)
    {
      cout << "\r " << i;
      filestr << "\n" << i << ": ";
      for (j = 0; j < tree[i].size (); j++)
    filestr << " " << (int) tree[i].at (j) << " ;";
      filestr << "*";
    }
  filestr.close ();

  return 0;
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]