// Uses cursorT to target a square and send that "attack" to the other
// arduino. Waits to receive the result and updates the local info.
bool Fire(int8_t* Array) {
  // Select a square
  int8_t target = CursorT(Array);
  // write that square to the other arduino.
  Serial3.write(target);
  // waits for a result.
  while( !Serial3.available() ) {}
  // reads the result.
  int8_t result = Serial3.read();
  
  // if the result is greater than 10, we know we sunk a ship.
  if( result/10 ) {
    Write_Message("You sunk a ship!");
  }
  // %10 ensures that a 12 (ship sunk) becomes a 2 (hit), otherwise, has
  // no effect (nothing else greater than 10 should be read).
  Array[target] = result%10;
  
  // draws the resulting image patch to the target square.
  lcd_image_draw(&Images[Array[target]%10], &tft, 0, 0,
          (12*(target%10))+8, (12*(target/10))+8, 12, 12);
  // return a 1 if a ship was sunk, in order to decrement the counter
  // of the other players remaining ships. return 0 otherwise.
  delay(3000); // This delay allows a player to view the result of their
               // shot, and also makes an approximate synchronization
               // with the other player's delay from the sound effect.
  return result/10;
}
Beispiel #2
0
void AP_Logger::Write_MessageF(const char *fmt, ...)
{
    char msg[65] {}; // sizeof(log_Message.msg) + null-termination

    va_list ap;
    va_start(ap, fmt);
    hal.util->vsnprintf(msg, sizeof(msg), fmt, ap);
    va_end(ap);

    Write_Message(msg);
}
int main() {
  // Initialize arduino, serial communication, lcd screen, buttons (and
  // internal pull-up resistors), LED pins, and SD card.
  init();
  Serial.begin(9600);
  Serial3.begin(9600);
  while(Serial3.available()) {Serial3.read();} // Clean the Serial line
  tft.initR(INITR_BLACKTAB);

  pinMode(SEL, INPUT);
  digitalWrite(SEL, HIGH);
  pinMode(Button1, INPUT);
  digitalWrite(Button1, HIGH);
  for (int i = 0; i < 10; ++i) {
    pinMode(i + 22, OUTPUT);
  }
  int click;    // This will be used to continue from the Title Screen

  Serial.print("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("failed!");
  }
  Serial.println("OK!");

  // do the auto calibration of the cursor (found in Cursor.cpp)
  Initialize_Cursor();


  while(true) {
    // draw the title screen, and set the turn pin to neutral (blue)
    lcd_image_draw(&Images[title], &tft, 0, 0, 0, 0, 128, 160 );
    digitalWrite(bluePin, HIGH);
    while (true) { // leave the title page with a joystick button press.
      click = digitalRead(SEL);
      if (!click) {break;}
    }
    // draw a black screen
    tft.fillScreen(0);
    // draw the border image (note that the numbers (0-9) and
    // letters (A-J) are just for appearance and aren't actually used by
    // the program).
    lcd_image_draw(&Images[border], &tft, 0, 0, 0, 0, 128, 128 );

    // initialize My_Ocean so that each value is 0 (water)
    for( int i=0; i<100; i++ ) {
      My_Ocean[i] = 0;
    }
    // initialize Their_Ocean so that each value is 1 (miss). This needs to
    // be nonzero for the first drawing of the screen (occurs on line 47
    // of Place_Ships.cpp) and will be set to 0 after.
    for( int i=0; i<100; i++ ) {
      Their_Ocean[i] = 1;
    }
    //==================== Initialization complete =================

    // Allows a player to place their ships
    My_Ships = Place_Ships(My_Ocean, Their_Ocean);
    // set Their_Ocean so that each value is 0 (water).
    for( int i=0; i<100; i++ ) {
      Their_Ocean[i] = 0;
    }
    // One arduino should read high, and the other should read low
    // (see wiring instructions for more detail). This determines who
    // gets the first turn.
    bool Turn = digitalRead(13);
    // Initialize the number of ships remaining for each player to 5.
    // can be set to 1 for a "debug" mode to see the victory/reset more
    // quickly.
    int Mine_Alive = 5;
    int Their_Alive = 5;

    // Turn on all the LED's initially (because all 10 ships should be
    // alive).
    for (int i = 0; i < 10; i++) {
      digitalWrite(22+i , HIGH);
    }

    // Connect to opponent. One arduino writes 'R' for ready, then waits
    // to receive a response. The other waits to read 'R' first, then
    // writes it.
    Write_Message("Connecting...");
    if( Turn == 1 ) {
      Serial3.write('R');
      while( Serial3.read() !='R' ) {}
    }
    else {
      while( Serial3.read() !='R' ) {}
      Serial3.write('R');
    }

    //==================== Ready to communicate/play ===============

    // Loop until either player has no ships left.
    while((Mine_Alive != 0) && (Their_Alive != 0)) {

      // My turn
      if( Turn == 1 ) {
        // draw a red square in the top left corner (because we will
        // view what we know of Their_Ocean).
        tft.fillRect(0, 0, 8, 8, 0xF800);
        // Make the LED green because it is our turn.
        digitalWrite(redPin, LOW);
        digitalWrite(greenPin, HIGH);
        digitalWrite(bluePin, LOW);
        // Draw Their_Ocean
        Draw_Screen(Their_Ocean, My_Ocean);
        // Indicate our turn at the bottom of the screen
        Write_Message("Your Turn");
        // Call Fire. It will return one (decrementing Their_Alive)
        // if it sinks a ship.
        Their_Alive = Their_Alive - Fire(Their_Ocean);
        // change turns
        Turn = 0;
      }
      else if( Turn == 0 ) {
        // draw a green square in the top left corner (because we will
        // view our own ships (My_Ocean).
        tft.fillRect(0, 0, 8, 8, 0x07E0);
        // Make the LED red because it is their turn.
        digitalWrite(redPin, HIGH);
        digitalWrite(greenPin, LOW);
        digitalWrite(bluePin, LOW);
        // draw My_Ocean
        Draw_Screen(My_Ocean, Their_Ocean);
        // Indicate their turn at the bottom of the screen
        Write_Message("Opponent's turn");
        // Call Get_Shot_At. It will return one (and will decrement
        // Mine_Alive) if a ship is sunk.
        Mine_Alive = Mine_Alive-Get_Shot_At(My_Ocean, My_Ships);
        // change turns
        Turn = 1;
      }
      // update the LEDs based on the number of ships left alive. The
      // Green LEDS represent the number of ships you have alive while
      // the Red ones do the same for the other players ships.
      for (int i = 5; i > 0; i--) {
        if (Their_Alive >= i) {
          digitalWrite(21 + 2*i , HIGH);
        }
        else {
          digitalWrite(21 + 2*i ,  LOW);
        }
      }
      for (int i = 5; i > 0; i--) {
        if (Mine_Alive >= i) {
          digitalWrite(20 + 2*i , HIGH);
        }
        else {
          digitalWrite(20 + 2*i , LOW);
        }
      }
    }

    // The delays help everything to sync up with the sound effects.
    delay(2000);
    if( Mine_Alive > 0 ) {
      // The number sent to the 'Victory_Cascade()' is to indicate which
      // set of LEDS are to be cascaded based on which player is the
      // winner of the game. The spaces in the message are in place to
      // avoid the word in the messages being cut off
      Write_Message("You won! Please hold joystick button to   play again.");
      Sound_Victory();
      Victory_Cascade(22);
    }
    else {
    delay(3000);
      Write_Message("You lost! Please holdjoystick button to  play again.");
      Victory_Cascade(23);
    }
  }
  Serial3.end();
  Serial.end();
  return 0;           // End of function
}
// Waits for an "attack" then calculates its result and write the result
// arduino. Also updates our own information with the result.
bool Get_Shot_At(int8_t* Array, Ship* Ships) {
  // Waits for an "attack" through serial3.
  while( !Serial3.available() ) {}
  // reads which square has been targeted.
  int8_t target = Serial3.read();
  
  // If that square has 0 or 1 (water or miss).
  if( Array[target] <=1 ) {
    // set its value to 1 (miss)
    Array[target] = 1;
    // Write a 1 (miss) to other arduino.
    Serial3.write(1);
    // draw a miss square
    lcd_image_draw(&Images[miss], &tft, 0, 0,
          (12*(target%10))+8, (12*(target/10))+8, 12, 12);
    // play a miss sound effect.
    Sound_Miss();
  }
  // If that square has 2 (already been hit)
  else if( Array[target] == 2) {
    // Write a 2 (so that other arduino still has the correct data)
    Serial3.write(2);
    // But, play a miss sound effect.
    Sound_Miss();
  }
  // By elimination, a ship must have been hit. Calls Hit_My_Ship
  else{
    // If Hit_My_Ship returns 1, a ship has been sunk.
    if( Hit_My_Ship(Array, target, Ships) ) {
      Write_Message("They sunk a ship!");
      // The two represents a hit (for the image patch), the 10 denotes
      // that a ship has been sunk.
      Serial3.write(12);
      // set our array to 2 (hit)
      Array[target] = 2;
      // draw a hit square
      lcd_image_draw(&Images[Array[target]%10], &tft, 0, 0,
          (12*(target%10))+8, (12*(target/10))+8, 12, 12);
      // play a hit sound effect.
      Sound_Hit();
      // return 1 to decrement our counter of how many ships are alive.
      return(1);
    }
    else { // A ship was not sunk.
      // Write back a 2 (hit)
      Serial3.write(2);
      // set our array to 2 (hit)
      Array[target] = 2;
      // draw a hit square
      lcd_image_draw(&Images[Array[target]%10], &tft, 0, 0,
          (12*(target%10))+8, (12*(target/10))+8, 12, 12);
      // play a hit sound effect.
      Sound_Hit();
    }
  }
  // Note that the playing of the sound effects creates an adequate
  // delay to allow a player to view the effects of the shot.
  // (about 4 seconds).
  // if a ship has not been sunk, return 0.
  return 0;
}
Beispiel #5
0
void AP_Logger::Write_Message(const char *message)
{
    FOR_EACH_BACKEND(Write_Message(message));
}