/**********************************

 **    File:       windows.c     **

 **    Programmer: Marc Douet    **

 **    Date:       09/12/02      **

 **********************************/

#include <stdio.h>
#include <stdlib.h>
#include "string.h"

#define  TRUE         1
#define  FALSE        0
#define  SCREEN_DIM   4
#define  NUM_WINDOWS  9

/**********************

 ** Global Variables **

 **********************/
int screen[SCREEN_DIM][SCREEN_DIM];
int expectedScreen[SCREEN_DIM][SCREEN_DIM]; 
int validRows[NUM_WINDOWS][2];
int validCols[NUM_WINDOWS][2];


/* 

 * Function:     void initValidArgs(void)

 * 

 * Description:  Initializes the arrays that specify the valid locations

 *               on the screen for each window.

 */
void initValidArrays()
{
  /* Set valid rows/cols for window 1 */
  validRows[0][0] = 0;
  validRows[0][1] = 1;
  validCols[0][0] = 0;
  validCols[0][1] = 1;

  /* Set valid rows/cols for window 2 */
  validRows[1][0] = 0;
  validRows[1][1] = 1;
  validCols[1][0] = 1;
  validCols[1][1] = 2;

  /* Set valid rows/cols for window 3 */
  validRows[2][0] = 0;
  validRows[2][1] = 1;
  validCols[2][0] = 2;
  validCols[2][1] = 3;

  /* Set valid rows/cols for window 4 */
  validRows[3][0] = 1;
  validRows[3][1] = 2;
  validCols[3][0] = 0;
  validCols[3][1] = 1;

  /* Set valid rows/cols for window 5 */
  validRows[4][0] = 1;
  validRows[4][1] = 2;
  validCols[4][0] = 1;
  validCols[4][1] = 2;

  /* Set valid rows/cols for window 6 */
  validRows[5][0] = 1;
  validRows[5][1] = 2;
  validCols[5][0] = 2;
  validCols[5][1] = 3; 

  /* Set valid rows/cols for window 7 */
  validRows[6][0] = 2;
  validRows[6][1] = 3;
  validCols[6][0] = 0;
  validCols[6][1] = 1;

  /* Set valid rows/cols for window 8 */
  validRows[7][0] = 2;
  validRows[7][1] = 3;
  validCols[7][0] = 1;
  validCols[7][1] = 2;

  /* Set valid rows/cols for window 9 */
  validRows[8][0] = 2;
  validRows[8][1] = 3;
  validCols[8][0] = 2;
  validCols[8][1] = 3;
}


/*

 * Function:     void updateExpectedScreen(int window, int row, int col)

 *

 * Description:  Puts the passed-in window to the foreground if it is not  

 *               found at the passed-in coordinates of the expected screen.

 */
void updateExpectedScreen(int window, int row, int col)
{
  /* 

   * Only update the expected screen if the passed-in window was not found

   * at the passed-in coordinates of the expected screen.

   */
  if(expectedScreen[row][col] != window) {
		expectedScreen[validRows[window-1][0]][validCols[window-1][0]] = window;
		expectedScreen[validRows[window-1][0]][validCols[window-1][1]] = window;
		expectedScreen[validRows[window-1][1]][validCols[window-1][0]] = window;
		expectedScreen[validRows[window-1][1]][validCols[window-1][1]] = window;
  }
}


/*

 * Function:     void buildScreens(void)

 * 

 * Description:  Read in the locations of each window into the 'screen' array,

 *               building the 'expected' screen along the way.

 */
void buildScreens()
{
  int row, col;

  /* First clear the screens. */
  memset(screen, '0', sizeof(screen));
  memset(expectedScreen, '0', sizeof(expectedScreen));

  /* Read in the layout of each window, building the expected screen as we go. */
  for(row = 0; row < SCREEN_DIM; row++) {
      for(col = 0; col < SCREEN_DIM; col++) {
          scanf("%i", &screen[row][col]);
          updateExpectedScreen(screen[row][col], row, col);
      }
  }

  /* 

   * Make another pass over the read-in screen to catch any windows that got put

   * to the foreground that shouldn't have.

   */
  for(row = 0; row < SCREEN_DIM; row++) {
      for(col = 0; col < SCREEN_DIM; col++) {
          updateExpectedScreen(screen[row][col], row, col);
      }
  }
}


/* Function:     int windowsAreClean(void)

 *

 * Description:  Determine whether all of the window locations are valid by

 *               checking that the read-in screen matches the built screen.

 */
int windowsAreClean()
{
  int row,col;

  /* If the actual screen doesn't match the expected, the windows are broken! */
  for(row = 0; row < SCREEN_DIM; row++)
      for(col = 0; col < SCREEN_DIM; col++)
          if(screen[row][col] != expectedScreen[row][col])
              return FALSE;

  /* If we made it this far, the windows are clean! */
  return TRUE; 
}


/* 

 * Function:     int main(void)

 *

 * Description:  Main driver responsible for reading in data and printing

 *               the appripriate output response.

 */
int main()
{
  char tag[sizeof("START")];

  /* Initialize the valid row/col arrays. */
  initValidArrays();

  /* Read in the START tag. */  
  scanf("%s", tag);

  while(!strcmp(tag, "START")) {
      /* Read in the windows' configuration and build the actual and expected screens. */
      buildScreens();

      /* Determine whether the user's machine has crashed. */
      if(windowsAreClean()) 
          printf("THESE WINDOWS ARE CLEAN\n");
      else  
          printf("THESE WINDOWS ARE BROKEN\n");
      
      /* Read in the END tag. */
      memset(tag, '\0', sizeof(tag));
      scanf("%s", tag);

      /* Attempt to read in the START tag. */
      memset(tag, '\0', sizeof(tag));
      scanf("%s", tag); 
  }

  return 0;
}