you always need error handling for statements that can fail. you should also insure that you have php's error_reporting set to E_ALL and display_errors set to ON, in the php.ini on your development system, so that php will help you by reporting and displaying all the errors it detects. if you run this code on a live/public server, you would instead set display_errors to OFF and set log_errors to ON.
the mail() function returns either a true or a false value. for a false value, php will either display or log the actual error information, so that you will have an indication of the call failing. however, in your code for a false value, you should log your own information consisting of the datetime, the php error that occurred, and the parameter values that were supplied to the mail() call. this will let you debug problems that are occurring due to things like email addresses that cause an error. for a true value, because email can be unreliable, you should actually log or insert rows in a database table with the same information, so that you can check if you are receiving all the emails that are being sent.
once you do the above you will probably get errors about an invalid mail header, a missing From: header, and/or errors about relaying restrictions.
the mail headers must contain a From: email address. the syntax is From: email address \r\n this email address is NOT the address that was entered in your form. these emails are not being sent from the user's email address (except perhaps during testing that you may have done using an email address that does correspond to your web hosting.) they are being sent from the mail server at your web hosting. the email address in the From: header must correspond to your web hosting. you can put the entered email address into a Reply-to: mail header.
the are a number of issues with the posted code. the most immediate problems are -
the code is not indented properly, so you cannot see what exactly it is or is not doing. the current code will attempt to sent the email, even if the entered email address is not valid. you should actually store the user/validation errors in an array, using the field name as the array index. then, after the end of all the validation logic, if the array is empty, use the submitted data. this will simplify all the nested conditional logic. to display the errors, at the appropriate location in the html document, you would test if the array is not empty, then either loop over or implode the contents of the array to display the error messages.
the $body variable is being reassigned on each pass through the foreach(){} loop. this leaves you with only the last checkbox message as part of the body. since there could be any number of checkbox messages, i recommend that you add each one to an array, inside of the loop, then after the end of the loop, implode them with whatever markup you want between them, then append this to the end of the main message body.
don't write out code for each possible value. if you had 10 checkboxes, would writing out all that conditional logic 10X make sense? you should use a data-driven design, where you have a data structure (array or database table) that holds the definition of the data. for the checkboxes, you would have an entry in the defining array for each checkbox. the main array index would be the values (1,2,...) each entry in the main array would be an array with elements for the label, and the mail body text. you would use this defining data structure when dynamically building the checkbox markup, when validating the submitted checkbox values, and when adding the text to the mail body.