TweetFollow Us on Twitter

The Eight Queens Problem

Volume Number: 13 (1997)
Issue Number: 12
Column Tag: Programming Techniques

Solving The Eight Queens Problem

by F.C. Kuechmann

Using the graphics of a Macintosh to explore the recursion and backtracking-based solution to this common puzzle

One of the oldest and most familiar intellectual puzzles whose solution is uniquely suited to the computer is the eight queens problem, in which the goal is to systematically determine each of the 92 different ways eight queens can be placed on a chessboard without conflict. Of the 92 solutions, 12 [numbers 1, 2, 5, 6, 7, 8, 9, 10, 11, 14, 17 and 18] are unique; the remaining 80 are variations on the twelve -- mirror images on the vertical, horizontal or diagonal axes, or 90, 180 or 270 degree rotations.

Since queens can move any number of squares in any direction, each queen must be placed on its own row, column and diagonals. Niklaus Wirth [1976, 1986] describes it as a familiar problem and states that Gauss considered it as early as 1850. No straightforward mathematical formula has ever been devised for its solution. The trial-and-error method, often combined with such problem solving techniques as recursion and backtracking, while tedious and error prone for humans, is well-suited to the computer. (A computer doesn't get bored, make mistakes, or have a cat that jumps onto the chess board.) Each time the active queen is moved to a new position the new location is tested for conflict unless that position is off the board. In that case, we backtrack to the previous column or row, advance that previously secure queen, and proceed. Thus a backtrack involves a move without testing the new position for conflict. 981 queen moves (876 position tests plus 105 backtracks) are required for the first solution alone. 16,704 moves (14,852 tests and 1852 backtracks) are needed to find all 92 solutions. If we continue testing until all possibilities are exhausted, we've made 17,684 moves -- 15,720 tests plus 1964 backtracks. Given those figures, it's easy to see why the solution is best left to computers.

While text-oriented computers can determine the solutions as well as any, a graphically-oriented computer like the Mac is ideally suited for illustrating the underlying algorithm.

The widespread use of the personal computer as a teaching tool has contributed to the appearance of the eight queens problem in several textbooks in the past 20-plus years, including especially Wirth [1976, 1986] and Budd [1987, 1991, 1996]. Niklaus Wirth's solutions are in Pascal and Modula-2. Timothy Budd has discussed object-oriented solutions, in languages ranging from SmallTalk to Object Pascal to Java, in at least three books. Microware furnished a structured BASIC version of Wirth's Pascal solution with their BASIC09 interpreter, which probably received its widest distribution packaged for the Radio Shack Color Computer 2 and 3.

A web search on the phrase "eight queens" will uncover several graphic Java solutions, some interactive, based on a problem posed by Budd [1996]. For some reason with my PowerPC Mac 6500/225 and Quadra 650, Microsoft's Internet Explorer browser works better in displaying the interactive Java versions on the web than does Netscape's Navigator.

WIRTH's Algorithm

The queen conflict tracking mechanism employed by Wirth consists of three Boolean arrays that track queen status for each row and diagonal. TRUE means no queen is on that row or diagonal; FALSE means a queen is already there.

Figure 1 shows the mapping of the arrays to the chess board for Pascal. All array elements are initialized to TRUE. The Row array elements 1-8 correspond to rows 1-8 on the board. A queen in row n sets rows array element n to FALSE.

Column-Row array elements are numbered from -7 to 7 and correspond to the difference between column and row numbers.

A queen at column 1, row 1 sets array element zero to FALSE. A queen at column 1, row 8 sets array element -7 to FALSE.

The Column+Row array elements are numbered 2-16 and correspond to the sum of the column and row. A queen placed in column 1, row 1 sets array element 2 to FALSE. A queen placed in column 3, row 5 sets array element 8 to FALSE.

Figures 2, 3 and 4 show the changes in array element values as 1, 2 and 3 queens are placed on the board.

In Figure 2, Row array element 1, Column-Row array element 0, and Column+Row array element 2 are all set to FALSE.

Figure 2. One conflict queen

Figure 3. Two conflict-free queens.

In Figure 3, Row array element 3, Column-Row array element -1, and Column+Row Array element 5 are set also set FALSE.

Figure 4. Three conflict-free queens.

In Figure 4, Row Array element 5, Column-Row array element -2, and Column+Row array element 8 are added to the FALSE list.

It would require hundreds of pages to show the entire move sequence just for the first solution, which is shown in Figure 5. All 981 moves can be easily visualized by stepping through the program, either in single-step mode or at slow speed, while observing changes in the Boolean array values displayed to the right of the board, as queens are set and removed.

Figure 5. The first solution.

The Trouble With C

In the C language, with its zero-based arrays, the mapping of the arrays to the board is a bit more complicated. Array elements are numbered 0-n and the mapping of board positions to the arrays is compensated accordingly. The Row array elements 0-7 correspond to rows 1-8 on the board. A queen in row n sets Row array element n-1 to FALSE. Column-Row array elements are numbered from 0 to 14 and correspond to the difference between column and row numbers, plus 7. A queen at column 1, row 1 sets array element 7 (1-1+7=7) to FALSE. A queen at column 1, row 8 sets array element 0 (1-8+7=0) to FALSE. The Column+Row array elements are numbered 0-14 and correspond to the sum of the column and row, minus 2. A queen placed in column 1, row 1 sets array element 0 (1+1-2=0) to FALSE. A queen placed in column 3, row 5 sets array element 6 (3+5-2=6) to FALSE.

Many Ways to Tango

Recursive and non-recursive variations of Wirth's method are easy to implement on the Macintosh and other computers in most popular languages, including Pascal, C and structured BASIC. The major code differences between recursive and non-recursive variations are these:

  1. The non-recursive version adds an 8-element integer array to hold the queen row for each column; with recursion this housekeeping is handled by the system.
  2. The recursive program's main procedure uses a single for loop, with backtracking handled by the system, whereas the non-recursive version uses two nested repeat loops and a separate procedure to handle backtracking.

With these exceptions, the code for the two variations is identical.

In Pascal, the main loop of the recursive solution looks like this:

procedure Try(column:integer);
  begin
    for row := 1 to 8 do
      begin
        { code }
        if column < 8 then
          Try(column + 1)  { procedure calls itself }
        else
          PrintSolution;
        { code }
      end;    {for}
  end;

The core of the non-recursive solution:

    repeat
      repeat
        { code }
      until row > 8;
      backtrack;
    until column < 1;

Listing 1. Try Try

This procedure is called with a column value of 1 after initializing the gRowe, gColPlusRow and gColMinusRow Boolean arrays to TRUE. When it finishes, all 92 solutions have been found.

procedure Try (column: integer);
  var
    row: integer;
    rowFlag,plusFlag,minusFlag,: Boolean;
  begin
    for row := 1 to 8 do
      begin
        rowFlag := gRowe[row];
        plusFlag := gColPlusRow[column + row];
        minusFlag := gColMinusRow[column - row];

        if rowFlag and plusFlag and 
                          minusFlag then
          begin
            gSolutionStash[column] := row;
            SetQueen(row, column);
            if column < 8 then
              Try(column + 1)
            else
              PrintSolution;

            RemoveQueen(row, column);
          end;  {if k}
      end;    {for}
  end;    {Try}

Listing 1 shows the complete Try() procedure for a simplified, non-interactive version of the recursive solution. The for loop repeatedly tests the Boolean arrays at indices consisting of the row, sum of row and column, and difference between row and column. The initial row and column values are both 1. If these three Boolean tests are TRUE, a queen is placed in the current column and row positions; if the column value is 8, we have a queen in each column and print the solution. After printing, the queen in column 8 is removed and the row increments at the top of the loop in pursuit of the next solution.

Otherwise when column < 8, the Try() procedure calls itself with an incremented column value and position testing starts anew at row 1. If any of three Boolean array locations are FALSE, the for loop row index increments and the tests repeated. If row exceeds a value of 8 (that is, the active queen drops off the board), execution continues after the Try(column+1) line in the previous iteration of the procedure unless the column value equals 1 when row exceeds 8. (In that case, all solutions have been found and operation passes back to whatever called Try initially.) The queen at the row position for the current column is removed, the row increments at the top of the loop, etc.

Listing 2a. SetQueen

SetQueen

procedure SetQueen (row, column: integer);
  begin
    gRowe[row] := false;
    gColPlusRow[column + row] := false;
    gColMinusRow[column - row] := false;
  end;

Listing 2b. RemoveQueen

RemoveQueen

procedure RemoveQueen (row, column: integer);
  begin
    gRowe[row] := true;
    gColPlusRow[column + row] := true;
    gColMinusRow[column - row] := true;
  end;

Listing 2 shows the SetQueen and RemoveQueen procedures that update the Boolean arrays.

Listing 3a. Try

Try

procedure Try;
  var
    row, column: integer;
    rowFlag,plusFlag,minusFlag: Boolean;
  begin
    row := 1;
    column := 1;
    repeat
      repeat
        rowFlag := gRowe[row];
        plusFlag := gColPlusRow[column + row];
        minusFlag := gColMinusRow[column - row];
        if rowFlag and plusFlag and minusFlag then
          begin
            gSolutionStash[column] := row;
            SetQueen(row, column);
            if column < 8 then
              begin
                gRowForCol[column] := row;
                row := 1;
                Inc(column);
                Leave;
              end
            else
              begin
                PrintSolution;
                RemoveQueen(row, column);
                Inc(row);
              end;
          end
        else
          Inc(row);
      until row > 8;

      if row > 8 then
        BakTrak(row, column);

  until column < 1;
end;    {procedure Try}

Listing 3b. BakTrak

BakTrak

procedure BakTrak (var row, column: integer);
  begin
    repeat
      Dec(column);
      if column > 0 then
        begin
          row := gRowForCol[column];
          RemoveQueen(row, column);
          Inc(row);
        end;
    until (row < 9) or (column < 1);
  end;

Listing 3 gives the Try and BakTrak procedures for a non-recursive solution. The biggest differences from Listing 1 are the two nested repeat loops the global array gRowForCol, which holds the row number of the queen in each column.

These listings generate only the row number for the queen in each column and do not show the event-handling calls or other fancifications needed to implement an interactive program with variable execution speeds, single-step mode, etc. For that, see Listing 4 and the full source code files.

Listing 4. DoColumns

DoColumns

I call this procedure DoColumns instead of Try in order to distinguish it from the corresponding procedure in my "sideways" solution, which is called DoRows.

procedure DoColumns (column: Integer);
  var
    row,n,rotNum,rotSize: integer;
    rowFlag,plusFlag,minusFlag,mirFlag,whiteDiagFlag,
      redDiagFlag,topBotFlipFlag,leftRtFlipFlag,
      rotFlag: boolean;
    elapsedTime,currentTime: longint;
    bn : byte;
  begin
    ggCol   := column;
    for row := 1 to 8 do
      begin
          {update active queen position unless in ultra-fast}
        if not ggUfastFlag then
          begin
            DrawQueen(row, column);
            if not ggVfastFlag then
              UpDateBoolean;
          end;
          
          {test active queen for conflicts}
        rowFlag     := ggRowFlags[row];
        plusFlag   := ggColPlusRow[column + row];
        minusFlag   := ggColMinusRow[Column-Row];
        Inc(ggTests);
        UpdateTestCount;

            { put this here to update boolean display before halting }
            { in step mode -- if no conflict }
        if rowFlag and plusFlag and minusFlag then
          begin
            SetQueen(row, column);
            UpDateBoolean;
          end;

        if not ggUfastFlag then
          gBoardNotClear := true;  
                  {flag used in ultra-fast mode to clear}
                  {board completely 1st solution after}
                  {ultra-fast mode is selected; only   }
                  {those queens that have changed pos-}
                  {ition are erased subsequently  }

        if ggStepModeFlag = true then
          ggStepFlag := true
        else
          ggStepFlag := false;

        if (not ggVfastFlag) and (not ggUfastFlag)
                            and (not ggStepModeFlag) then
              {delay according to speed and mode}
          Stall(ggStallVal);  
          
          {handle events except in very-fast or ultra-fast modes}
        if ((not ggUfastFlag) and (not ggVfastFlag))
                                or ggStepModeFlag then
          begin
            repeat
              HandleEvent;
            until (not ggStepFlag) or ggDoneFlag;
          end;
        if not ggStartClockFlag then
          begin
            ggStartClockFlag := true;
            GetDateTime(ggStartTime);
            if not gRunFlag then
              begin
                GetDateTime(ggStartTotalTime);
                gRunFlag := true;
              end;
          end;

        if rowFlag and plusFlag and minusFlag then
          begin
              {active queen position is ok, so save row}
            ggRowStash[ggSolNum, column] := row;
              {no solution yet; do next column}
            if column < 8 then
              begin
                Inc(column);
                ggCol := column;
                  {procedure calls itself}
                DoColumns(column);

                if not ggUfastFlag then
                  Stall(ggStallVal);
                Dec(column);
                  {ggCol is used in event-triggered board redraws}
                ggCol := column;  

                Inc(ggBakTrak);
                UpDateBakTrax;
                if ggStepModeFlag = true then
                  begin
                    ggStepFlag := true;
                    while ggStepFlag = true do
                      HandleEvent;
                  end
                else if not ggUfastFlag then
                  HandleEvent;

                if column > 0 then
                  begin
                    if not ggUfastFlag then
                      SnuffQueen(row, column);
                    RemoveQueen(row, column);
                  end;
              end
            else
              begin
                {we have a conflict-free queen in each column}
                {In ultra - fast mode we need to update the}
                {board and statistics}

                if ggUfastFlag then
                  begin
                    DoUfastUpdate;
                    UpDateBoolean;
                    UpdateTestCount;
                    UpdateBakTrax;
                    GetDateTime(currentTime);
                    elapsedTime := currentTime - 
                                        ggStartTime;
                    DrawElapsed(elapsedTime);
                  end;
                  
                  {get ready to test for unique solution}
                InitForMirrors(rotFlag, whiteDiagFlag, 
                  redDiagFlag,topBotFlipFlag,leftRtFlipFlag,
                   mirFlag, gMirrorNum);
                    {freeze time counter}
                ggStartClockFlag := false;
                    { no board redraws}     
                ggShowFlag := true;
                TestForMirrors(gMirrorNum,rotNum,rotSize,
                  mirFlag,whiteDiagFlag,redDiagFlag, 
                  topBotFlipFlag, leftRtFlipFlag, rotFlag);
                ggShowFlag := false;
                if (not mirFlag) and (not rotFlag) then
                  begin
                    ggUniqueSols[ggSolNum] := gUniqueSolNum;
                    Inc(gUniqueSolNum);
                  end;

                DrawSolStatus(mirFlag,whiteDiagFlag,
                  redDiagFlag,topBotFlipFlag,leftRtFlipFlag,
                  rotFlag,gMirrorNum,gUniqueSolNum,rotNum,
                  rotSize);

                ggSolFlag := TRUE;    {avoid board redraw}
                if not ggWaitFlag then
                  WaitDelaySecs
                else
                  begin    
                        {wait for run or step button push or quit}
                        {set up and call event handler}
                    ShowControl(ggStepButtonHdl);
                    HiliteControl(ggStepButtonHdl, 0);
                    ShowControl(ggRunButtonHdl);
                    HiliteControl(ggRunButtonHdl, 0);
                    ShowControl(ggStepButtonHdl);
                    HiliteControl(ggStepButtonHdl, 0);
                    SetControlTitle(ggRunButtonHdl, 'Run');
                    ggStepModeFlag := true;
                    ggStepFlag := true;
                    repeat
                      HandleEvent;
                    until (not ggStepModeFlag) or
                          (not ggStepFlag) or ggDoneFlag;

              {STEP button pushed in fast modes plus wait}
              { so drop to medium speed, step mode}
                    if (ggUfastFlag or ggVfastFlag) and
                                  (ggStepModeFlag and
                                  (not ggStepFlag)) then
                      begin
                        ggUfastFlag:= false;
                        ggVfastFlag:= false;
                        ggSpeedMenuHdl:=
                          GetMenuHandle(ggcSPEED_MENU_ID);
                        CheckItem(ggSpeedMenuHdl,
                                  ggOldSpeed,
                                  ggcREMOVE_CHECK_MARK);
                        CheckItem(ggSpeedMenuHdl,
                                  ggcMEDIUM_ITEM,
                                  ggcADD_CHECK_MARK);
                        ggOldSpeed := ggcMEDIUM_ITEM;
                        ggStallVal := gcMedium;
                      end;
                  end;

                    {init the next solution}
                for n := 1 to 8 do
                  begin
                    bn := ggRowStash[ggSolNum, n];
                    ggRowStash[ggSolNum + 1, n] := bn;
                  end;

                if not ggUfastFlag then
                  SnuffQueen(row, column);
                Inc(ggSolNum);
                DrawSolNum;
                GetDateTime(ggStartTime);
                ggStartClockFlag := true;  {start the clock}
                elapsedTime := 0;
                DrawElapsed(elapsedTime);
                RemoveQueen(row, column);
                EraseSolStat;
                gTotalTests:=gTotalTests+ggTests;
                gTotalMoves:=gTotalMoves+ggTests+ggBakTrak;
                gTotalTestsSol:=gTotalTestsSol+ggTests;
                gMovesForSol:=gMovesForSol+ggBakTrak+
                                        ggTests;
                EraseTestCount;
                ggTests := 0;
                UpdateTestCount;
                EraseBakTrax;
                ggBakTrak := 0;
                UpDateBakTrax;
                EraseTime;
                  {allow board redraws}
                ggSolFlag := FALSE;  
              end;
          end
        else
          begin
            if not ggUfastFlag then
              SnuffQueen(row, Column);
          end;

        if ggDoneFlag then
          Leave;
      end; {for}

  end;    {procedure DoColumns}

Listing 4 shows the recursive version of the Eight Queens program's main loop all dressed up for the event-driven Macintosh party with speed and mode variations.

Running the Program

The Macintosh programs EightQueens I and EightQueens II have two operating modes -- run and single-step. At startup, the chessboard is drawn and a startup window is displayed for 30 seconds or until the Go button is pushed. To the right of the chess board is an area giving the following information:

  • The time to achieve each solution.
  • The solution number 1-92.
  • The solution status -- unique or variation on a prior solution.
  • The number of position tests required to achieve each solution.
  • The number of backtracks.
  • The values of the elements of the Row or Column, Column plus Row, and Column minus Row Boolean arrays used to determine the conflict status of the queens.

All but the 2nd and 3rd are updated continuously as each solution progresses.

At bottom right are the Run and Step buttons. In single-step mode, pushing the Step button single-steps the currently-active queen. Pushing the Run button causes. Push the Step button to re-select single-step mode.

The program operates initially in single-step mode in which the active queen steps when the Step button is pressed. If the Run button is pressed, run mode is entered; the Step button disappears, the Run button is re-labeled Step, and the active queen steps continuously until a solution is achieved. It then delays (default delay is 10 seconds) before stepping to the next solution unless Wait is selected from the Delay menu. Both the step rate and the duration of the delay can be varied via the Speed and Delay menu. Speeds vary from about 1 step per second at the slow end to hundreds per second. Default speed is about 4 steps per second on a PowerPC Mac 6500/225. The delay between solutions can be varied from none to 30 seconds in 5-second increments, or Wait can be selected and the program will enter single-step mode after each solution. The Step button changes to Next, and the program waits for a click on the Run or Next button.

To determine whether a solution is unique or a variation on one of the twelve unique solutions, the program creates seven variations of each solution to compare with the previous ones. The variations are -- left-to-right flip (vertical axis mirror), top-to-bottom flip (horizontal axis mirror), upper-left-to-lower-right (red) diagonal mirror, lower-left-to-upper-right(white) diagonal mirror, and 90 degree, 180 degree and 270 degree clockwise rotations. To view these in sequence, click the Next button. The variations will continue to be displayed in sequence as long as the Next button is clicked.

If you click the Run button, the Next button is re-labeled Step, and the solution status line tells whether the solution is unique or variant. When the status line says, for example, at solution #12, Rotate 90 deg CW #10, it means "rotating solution #12 90 degrees clockwise gets solution #10"; at solution #21 "Left-Right Flip #11" means that, if solution #21 is flipped left-to-right, we get solution #11. At #13 , "Red diag mir #8" means that if solution #13 is flipped on the red (upper-left-to-lower-right) diagonal axis, we get solution #8. Solution #16 is a white (lower-left-to-upper-right) diagonal axis mirror of solution #8. Solution #75 is a top-to-bottom flip of #18, etc.

Clicking the Run button again steps the active queen continuously at the previous speed to the next solution, while clicking Step single-steps the active queen and sets the speed to Medium. When the program ceases pursuing solutions either because all possibilities have been exhausted or because Quit has been selected from the File menu (or Command-Q from the keyboard), the area to the right of the board clears and displays statistics on the number of solutions achieved, number of position tests and backtracks, etc. The right button appears, labeled Stop, while the left button is labeled Run. The user can then choose to either resume seeking solutions starting at the beginning by clicking Run, or terminate operation by clicking Stop.

Sourcecode

Sourcecode for two variations of Wirth's algorithm for solving the eight queens problem is supplied for CodeWarrior Professional Pascal. Those readers familiar with Dave Mark's books may notice some resemblances between the eight queens sourcecode and some of that found in Dave's books -- things like some of the names of constants and general structure of the event loop. The resemblance isn't accidental. I used the Timer project from the Macintosh Pascal Programming Primer, Vol. 1, by Dave Mark and Cartwright Reed, as a "skeleton" for EightQueens. While most of the code is mine, underneath there's still a bit of Mark and Reed code holding things together.

Variations

Wirth's recursive algorithm used in EightQueens I indexes rows in the single for loop and columns via recursion, but the method works equally well if the rows and columns are switched. The movement of the queens is then from left-to-right, starting at the top row. We get the same 92 solutions, but in a different order. The first solution with horizontal queen movement is the same as the fourth with vertical movement. Each solution, however, takes the same number of tests and backtracks as with Wirth's algorithm -- 876 tests and 105 backtracks for the first solution, 264 tests and 33 backtracks for the second, 200 tests and 25 backtracks for the third, etc. The reason becomes obvious if you think about it. Take the board set for vertical queen movement, with a single queen upper left. Flip the board on the vertical axis so the queen is in the upper right corner, then rotate it 90 degrees counter-clockwise to put the queen upper left. Start successive queens in column one, incrementing left-to-right. Test queens have exactly the same positions relative to the first queen as in Wirth's original approach. EightQueens II shows this "sideways" approach implemented non-recursively using two nested repeat loops.

Bibliography and References

  • Wirth, Niklaus, Algorithms + Data Structures = Programs, (Englewood Cliffs NJ: Prentice-Hall, 1976).
  • Wirth, Niklaus, Algorithm s and Data Structures, (Englewood Cliffs NJ: Prentice-Hall, 1986)
  • Budd, Timothy, A Little Smalltalk, (Reading, MA: Addison-Wesley, 1987).
  • Budd, Timothy, An Introduction to Object-Oriented Programming, (Reading, MA: Addison-Wesley, 1991).
  • Budd, Timothy, An Introduction to Object-Oriented Programming, 2nd Edition, (Reading, MA: Addison-Wesley, 1996).

F.C. Kuechmann, fk@aone.com, is a hardware designer, programmer and consultant with degrees from the University of Illinois at Chicago and Clark College who is currently building a programmers' clock that gives the time in hexadecimal.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

OmniGraffle Pro 7.2.2 - Create diagrams,...
OmniGraffle Pro helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use... Read more
OmniGraffle 7.2.2 - Create diagrams, flo...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
Spotify 1.0.44.100. - Stream music, crea...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
Microsoft OneNote 15.29 - Free digital n...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more
WALTR 2 2.0.8 - $39.95
WALTR 2 helps you wirelessly drag-and-drop any music, ringtones, videos, PDF, and ePub files onto your iPhone, iPad, or iPod without iTunes. It is the second major version of Softorino's critically-... Read more
Dropbox 16.3.27 - Cloud backup and synch...
Dropbox is an application that creates a special Finder folder that automatically syncs online and between your computers. It allows you to both backup files and keep them up-to-date between systems... Read more
EtreCheck 3.1.5 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
Carbon Copy Cloner 4.1.12 - Easy-to-use...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
VueScan 9.5.62 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
SpamSieve 2.9.27 - Robust spam filter fo...
SpamSieve is a robust spam filter for major email clients that uses powerful Bayesian spam filtering. SpamSieve understands what your spam looks like in order to block it all, but also learns what... Read more

Latest Forum Discussions

See All

Track Santa with these three festive app...
Christmas is fast approaching and that means it's time to prepare for Santa's yearly pilgrimage around the globe. Christmas Eve is an exciting time as parents help their kids get ready to welcome Santa. You've got the cookies and milk all planned... | Read more »
Galaxy on Fire 3 and four other fantasti...
Galaxy on Fire 3 - Manticore brings the series back for another round of daring space battles. It's familiar territory for folks who are familiar with the franchise. If you've beaten the game and are looking to broaden your horizons, might we... | Read more »
The best apps for your holiday gift exch...
What's that, you say? You still haven't started your holiday shopping? Don't beat yourself up over it -- a lot of people have been putting it off, too. It's become easier and easier to procrastinate gift shopping thanks to a number of apps that... | Read more »
Toca Hair Salon 3 (Education)
Toca Hair Salon 3 1.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »
Winter comes to Darkwood as Seekers Note...
MyTona, based in the chilly Siberian city of Yakutsk, has brought a little festive fun to its hidden object game Seekers Notes: Hidden Mystery. The Christmas update introduces some new inhabitants to players, and with them a chance to win plenty of... | Read more »
Bully: Anniversary Edition (Games)
Bully: Anniversary Edition 1.03.1 Device: iOS Universal Category: Games Price: $6.99, Version: 1.03.1 (iTunes) Description: *** PLEASE NOTE: This game is officially supported on the following devices: iPhone 5 and newer, iPod Touch... | Read more »
PINE GROVE (Games)
PINE GROVE 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: A pine grove where there are no footsteps of people due to continuous missing cases. The case is still unsolved and nothing has... | Read more »
Niantic teases new Pokémon announcement...
After rumors started swirling yesterday, it turns out there is an official Pokémon GO update on its way. We’ll find out what’s in store for us and our growing Pokémon collections tomorrow during the Starbucks event, but Niantic will be revealing... | Read more »
3 reasons why Nicki Minaj: The Empire is...
Nicki Minaj is as business-savvy as she is musically talented and she’s proved that by launching her own game. Designed by Glu, purveyors of other fine celebrity games like cult favorite Kim Kardashian: Hollywood, Nicki Minaj: The Empire launched... | Read more »
Clash of Clans is getting its own animat...
Riding on its unending wave of fame and success, Clash of Clans is getting an animated web series based on its Clash-A-Rama animated shorts.As opposed to the current shorts' 60 second run time, the new and improved Clash-A-Rama will be comprised of... | Read more »

Price Scanner via MacPrices.net

New 2016 13-inch Touch Bar MacBook Pros on sa...
B&H Photo the new 2016 Apple 13″ 2.9GHz/256GB Touch Bar MacBook Pros on sale for $50 off MSRP, each including free shipping plus NY sales tax only: - 13″ 2.9GHz/256GB Touch Bar MacBook Pro Space... Read more
12-inch 1.2GHz Space Gray Retina MacBook on s...
B&H Photo has dropped their price on the 2016 Apple 12″ 1.2GHz Space Gray Retina MacBook (MLH82LL/A) to $1399 including free shipping plus NY sales tax only. Their price is $200 off MSRP, and it’... Read more
Never Settle for Low Performing Wifi With iOS...
AppYogi Software has announced the release of WiFi Signal Strength Status App 1.0, the company’s new utility developed exclusively for macOS. WiFi Signal Strength Status App features a unique, single... Read more
New 2016 13-inch Touch Bar MacBook Pros in st...
B&H Photo has stock of new 2016 Apple 13″ Touch Bar MacBook Pro models, each including free shipping plus NY sales tax only: - 13″ 2.9GHz/512GB Touch Bar MacBook Pro Space Gray: $1999 - 13″ 2.... Read more
New 2016 15″ Touch Bar MacBook Pros in stock...
B&H Photo has new 2016 Apple 15″ Touch Bar MacBook Pro models in stock today including free shipping plus NY sales tax only: - 15″ 2.7GHz Touch Bar MacBook Pro Space Gray: $2799 - 15″ 2.7GHz... Read more
DietSensor App Targeting Diabetes and Obesity...
DietSensor, Inc., a developer of smart food and nutrition applications designed to fight diabetes and obesity and help improve overall fitness, has announced the launch of its DietSensor app for... Read more
Holiday 2016 13-inch 2.0GHz MacBook Pro sales...
B&H has the non-Touch Bar 13″ MacBook Pros in stock today for $50-$100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.0GHz MacBook Pro Space Gray (MLL42LL/A): $1449 $... Read more
Holiday sale: Apple TVs for $51-$40 off MSRP,...
Best Buy has dropped their price on the 64GB Apple TV to $159.99 including free shipping. That’s $40 off MSRP. 32GB Apple TVs are on sale right now for $98 on Sams Club’s online store. That’s $51 off... Read more
12-inch Retina MacBooks, Apple refurbished, n...
Apple has restocked a full line of Certified Refurbished 2016 12″ Retina MacBooks, now available for $200-$260 off MSRP. Refurbished 2015 models are available starting at $929. Apple will include a... Read more
Holiday sale: 12-inch Retina MacBook for $100...
B&H has 12″ Retina MacBooks on sale for $100 off MSRP as part of their Holiday sale. Shipping is free, and B&H charges NY sales tax only: - 12″ 1.1GHz Space Gray Retina MacBook: $1199 $100... Read more

Jobs Board

Integration Technician, *Apple* - Zones, In...
…at Zones and for our customers each day. Position Overview The Apple Integration Technician will be responsible for performing customer specific configuration Read more
*Apple* Brand Ambassador (Macy's) - The...
…(T-ROC), is proud of its unprecedented relationship with our partner and client, APPLE ,in bringing amazing" APPLE ADVOCATES"to "non" Apple store locations. Read more
*Apple* Retail - Multiple Positions- Trumbul...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
US- *Apple* Store Leader Program - Apple (Un...
…Summary Learn and grow as you explore the art of leadership at the Apple Store. You'll master our retail business inside and out through training, hands-on Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.