#include<iostream>

using namespace std;

//Function Declaration

// Place walls and players in world
void initialize(char world[][8],char directions[]);

// Display elements in world
void showWorld(char world[][8],char directions[]);

// Find location of a player (query: 'A', 'B', or 'C')
// in the world, providing the x (row) and y (column)
// coordinates through the last two formal parameters
void find(char world[][8], char query, int &x,int &y);

// Convert from player symbol to corresponding number:
// 'A'->1,  'B'->2,  'C'->3
int playerNumber(char playerSymbol);

// If valid to move player one step forward in the direction
// it is facing, move the player in the world
void move(char world[][8], char directions[], int playerNum);

// Turn player in newDirection
void turn(char directions[],int playerNum, char newDirection);


// MAIN FUNCTION:

int main()
{
 /* Establish 8x8 world and record of the three
  * players' facing directions
  * Each entry in the world is either
  *   'O' for open space, 'W' for wall
  *   'A', 'B', or 'C' for player
  * Each player can have a direction
  *   'U' for up, 'D' for down, 'L' for left, 'R' for right
  */
 char world[8][8], directions[3];


 // Initialize world and show its initial state
 initialize(world,directions);
 showWorld(world,directions);


 /* Prepare to loop through players 1 through 3
  * (alternatively labeled 0 through 2 in terms
  * of matrix indices)
  */
 int playerNum=0;
 char instruction, newDirection;

 // Perpetually loop through players, getting new
 // move and turn instructions for each
 while(true)
 { // Get move or turn instruction
   cout << "[M]ove forward or [T]urn? ";
   cin >> instruction;

   // Move instruction
   if(instruction=='M')
     move(world,directions,playerNum+1);

   // Turn instruction
   else if(instruction=='T')
   {
     cout << "Pick a turning direction ([L]eft, [R]ight, [U]p, or [D]own: ";
     cin >> newDirection;
     turn(directions,playerNum+1, newDirection);
   }

   // Show how the world looks after the last command was
   // executed
   showWorld(world,directions);

   
   // Move on to next player for the next loop repetition
   playerNum++;
   playerNum %= 3;
 }
 
 return 0;
}


// FUNCTION DEFINITIONS


// Move player forward by one step, if possible
void move(char world[][8], char directions[], int playerNum)
{
 // Find character
 char playerLetter;

 switch(playerNum)
 {
   case 1: playerLetter='A'; break;
   case 2: playerLetter='B'; break;
   case 3: playerLetter='C'; break;
 }

 
 // Find location of player
 int x,y;
 find(world,playerLetter,x,y);

 
 // Determine location of "one step forward",
 // given player's facing direction
 int xNew=x,yNew=y;
 switch(directions[playerNum-1])
 {
   case 'U' :  xNew=x-1; break;
   case 'D' :  xNew=x+1; break;
   case 'L' :  yNew=y-1; break;
   case 'R' :  yNew=y+1; break;
 }


 // Determine whether new location is valid
 bool validLocation=true;
 // Is location on the board?
 if(xNew<0 || xNew>7 || yNew<0 || yNew>7)
   validLocation=false;
 if(validLocation && world[xNew][yNew]!='O')
   validLocation=false;


 // If location is valid, update the world
 if(validLocation) {
   world[xNew][yNew]=playerLetter;
   world[x][y]='O';
 }

 return;
}



// Change player's direction
void turn(char directions[],int playerNum, char newDirection)
{
 directions[playerNum-1]=newDirection;
 return;
}



// Reports player number based on symbol on board
int playerNumber(char playerSymbol)
{
 switch(playerSymbol)
 {
   case 'A': return 1;
   case 'B': return 2;
   case 'C': return 3;
 }
}


// Initialize world to contain players, open
// spaces, and walls; each player gets a letter
// A, B, or C to indicate player number 1, 2, or
// 3 and each player gets a direction they are
// facing
void initialize(char world[][8], char directions[])
{
 // Fill in all positions with Open space
 for(int row=0; row<8; row++)
 {
   for(int col=0; col < 8; col++)
   {
      world[row][col]='O';
   }
 }

 // Fill in walls
 world[2][3]='W';  world[2][4]='W';
 world[4][7]='W';  world[6][2]='W';

 // Fill players (with their facing directions)
 // Player 1: 'A',  2: 'B',   3: 'C'
 world[2][6]='B';  world[3][1]='A';
 world[5][4]='C';
 // Right is 'R', Left is 'L', Up is 'U', Down is 'D'
 directions[0]='R'; directions[1]='U';
 directions[2]='D';
 
 return;
}


// Print out all the elements of the world in their
// locations
void showWorld(char world[][8],char directions[])
{
 int player_number;
 
 for(int row=0; row<8; row++)
 {
   for(int col=0; col<8; col++)
   {
     if(world[row][col]!='W' && world[row][col]!='O')
     { // If a player is at this location, show direction
// player is facing
// First: determine which number player it is
// (based on player letter A, B, or C)
        player_number=playerNumber(world[row][col]);

// Then: look up which direction player is facing
        switch(directions[player_number-1])
{
  case 'U' : cout << '^'; break;
  case 'L' : cout << '<'; break;
  case 'R' : cout << '>'; break;
  case 'D' : cout << 'V'; break;
}
     }

     else // if the position has a wall or is open
cout << world[row][col];
   } // end of code for column COL

   // Move to a new line when moving to a new row
   cout << endl;
 }
}


// Pre-conditions: input 8x8 world of chars, 1 "query" char to
//                 find on the world, and two pass-by-reference
//                 ints -- called x and y -- to record the
//                 location of the query
// Post-conditions: function changes x and y to the x- and y-
//                  coordinates of the query char inside the
//                  world
void find(char world[][8], char query, int &x, int &y)
{
 for(int i=0; i<8; i++)
 {  // check each row
   for(int j=0; j<8; j++)
   { // check each column
     if(world[i][j]==query) // record the location of the query
       { x=i;  y=j; }
   }
 }

}