Will the code I have written send an output to low within the parameters I set?

If the code for each zone does the exact same thing then it makes more sense to parameterize the code and have only one block instead of four. Then you will fix each mistake in one place instead of four places.

If this were my project I would probably store the info for each zone in an array of structures like this:

typedef struct {
  int sensorPin;    // soil sensor
  int valvePin;     // water valve
  int reading;      // mapped value
  int lcd_row;      // LCD coordinates for reading
  int lcd_col;
} zone;


zone zoneInfo[]  = {{A0, 2, 0, 0, 0}, {A1, 3, 0, 0, 9}, {A2, 4, 0, 1, 0}, {A3, 5, 0, 1, 9}};

const int NUM_ZONES = 4;  // # of zones to process
byte zoneIdx = 0;         // index to current zone

Each time through loop() I would only process one zone and would start with the value of NUM_ZONES set to 1 to test the first zone. When that zone was working it would be set to 2 to test the first two zones and so on.

With all the data held in an array and only one zone processed at a time the amount of code in the loop() function would be reduced.

void loop()
{
  //read the value from the soil moisture sensor
  int moistureValue = analogRead(zoneInfo[zoneIdx].sensorPin);

  if ( moistureValue <= potLow )
  {
    //open the valve
    digitalWrite(zoneInfo[zoneIdx].valvePin, HIGH);

  } else if ( moistureValue >= potHigh ) {

    //close the valve
    digitalWrite(zoneInfo[zoneIdx].valvePin, LOW);

  } // else

  //map zone range to 0-99
  zoneInfo[zoneIdx].reading = map(moistureValue, 0, 1023, 0, 99);

  //set the cursor
  lcd.setCursor(zoneInfo[zoneIdx].lcd_col, zoneInfo[zoneIdx].lcd_row);

  //print mapped value of zone1
  lcd.print(zoneInfo[zoneIdx].reading);

  // increment zone index, wrap to zero
  ++zoneIdx %= NUM_ZONES;

}