2016-04-06 3 views
0

Ich versuche, ein Spiel von Schlachtschiffen zu erstellen, in denen der Computer die Schlachtschiffe zufällig auf dem Brett legt.C++ Battleships Freiraum Funktion

Schlachtschiffe können nicht übereinander oder direkt nebeneinander platziert werden. Ich baute eine Funktion, um dies zu überprüfen und true zurückzugeben, wenn freier Speicherplatz verfügbar ist, aber aus irgendeinem Grund legt das Programm immer noch die Schiffe gegen die Regeln. Es passiert nicht jedes Mal, aber es passiert immer noch.

Hier ist die Funktion, die für freie Speicherplatz überprüft:

bool Game2::CheckPlace(int row, int column, DIRECTION direct, Battleship ship)//this function checks if a ship can be layed at the coordinates it recieved. 
{ 
    if (board[row][column] != '_' || board[row][column + 1] != '_' || board[row + 1][column + 1] != '_' || board[row + 1][column] != '_' || board[row - 1][column - 1] != '_' || board[row][column - 1] != '_' || board[row + 1][column - 1] != '_' || board[row + 1][column] != '_' || board[row + 1][column + 1] != '_') 
     return false; 
    if (direct == horizontal)//for horizontal direction 
    { 
     if (10 - column < ship.GetLength())//if there is no space left for the ship. 
      return false; 
     for (int i = 0; i < ship.GetLength(); ++i)//this loop creates a kind of a block that moves together to find surrounding ships. 
     { 
      if (row == 0 && column == 0 && (board[row + 1][column + i] != '_' || board[row + 1][column + 1 + i] != '_' || board[row][column + 1 + i] != '_'))//top left corner 
       return false; 
      if (row == 9 && column == 0 && (board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_') || board[row][column + 1 + i] != '_')//bottom left corner 
       return false; 
      if (row > 0 && row < 9 && column > 0 && column < 9 && board[row][column + 1 + i] != '_' || board[row + 1][column + 1 + i] != '_' || board[row + 1][column + i] != '_' || board[row + 1][column - 1 + i] != '_' || board[row][column - 1 + i] != '_' || board[row - 1][column - 1 + i] != '_' || board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_')//middle of the board 
       return false; 
      if (row == 0 && column > 0 && column < 9 && (board[row][column - 1 + i] != '_' || board[row][column + i] != '_' || board[row][column + 1 + i] != '_' || board[row + 1][column - 1 + i] != '_' || board[row + 1][column + i] != '_' || board[row + 1][column + 1 + i] != '_')) 
       return false; 
      if (row == 9 && column > 0 && column < 9 && (board[row - 1][column - 1 + i] != '_' || board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_' || board[row][column - 1 + i] != '_' || board[row][column + i] != '_' || board[row][column + 1 + i] != '_')) 
       return false; 
      if (column = 0 && row > 0 && row < 9 && (board[row + 1][column + i] != '_' || board[row + 1][column + 1 + i] != '_' || board[row][column + 1 + i] != '_' || board[row - 1][column + i] != '_' || board[row - 1][column + 1 + i] != '_')) 
       return false; 
     } 
     return true; 
    } 
    if (direct == vertical) 
    { 
     if (10 - row < ship.GetLength())//if there is no space left for the ship. 
      return false; 
     for (int i = 0; i < ship.GetLength(); ++i)//this loop creates a kind of a block that moves together to find surrounding ships. 
     { 
      if (row == 0 && column == 0 && (board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_')) 
       return false; 
      if (row == 0 && column == 9 && (board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_' || board[row + 1 + i][column] != '_')) 
       return false; 
      if (row == 0 && column > 0 && column < 9) 
       if (board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_' || board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_') 
        return false; 
      if (column == 0 && row > 0 && row < 9 && (board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_' || board[row - 1 + i][column + 1] != '_' || board[row - 1 + i][column] != '_')) 
       return false; 
      if (column == 9 && row > 0 && row < 9 && (board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_' || board[row + 1 + i][column] != '_' || board[row - 1 + i][column - 1] != '_' || board[row - 1 + i][column] != '_')) 
       return false; 
      if (row > 0 && row < 9 && column > 0 && column < 9) 
       if ((board[row + i][column + 1] != '_' || board[row + 1 + i][column + 1] != '_' || board[row + 1 + i][column] != '_' || board[row + i][column - 1] != '_' || board[row + 1 + i][column - 1] != '_' || board[row - 1 + i][column + 1] != '_' || board[row - 1 + i][column] != '_' || board[row - 1 + i][column - 1] != '_')) 
        return false; 
     } 
     return true; 

    } 
} 

Und hier ist ein Foto eines Beispiel Ausgabe: enter image description here

+1

Es klingt wie Sie lernen müssen, wie Verwenden Sie einen Debugger, um durch Ihren Code zu gehen. Mit einem guten Debugger können Sie Ihr Programm Zeile für Zeile ausführen und sehen, wo es von dem, was Sie erwarten, abweicht. Dies ist ein essentielles Werkzeug, wenn Sie programmieren wollen. Weiterführende Literatur: ** [Wie kleine Programme zu debuggen] (http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) ** – NathanOliver

+0

Warum verwenden Sie keine temporäre Karte Dies ist eine Kopie der Originalkarte. Füge das Schlachtschiff hinzu, indem du jedes Element mit tmp_board [x] [y] + = '_' zum temp-board hinzufügst und dann nachprüfst, ob jeder Wert des Schlachtschiffes nicht '_' ist. – Lucian

+0

'if (column = 0' sollte' == 'sein. Ein vernünftiger Compiler würde dies mit aktivierten Warnungen warnen. – interjay

Antwort

0

@interjay bereits beantwortete Ihre Frage die Fehler in dem Zustand, den Hinweis auf:

if (column = 0 ... // should be == 

Wie viele andere sagten, sollten Sie immer alle Warnungen aktivieren, die der Compiler auslösen kann. Sie können auch zuerst die Literale zu schreiben versuchen:

if (0 = column ... // that's an error every compiler can catch 

Der Hauptgrund, warum ich diese Antwort geschrieben hat, ist, dass ich Ihnen zeigen möchten, dass eine andere (vielleicht besser lesbar und weniger fehleranfällig) Algorithmus Ihre Aufgabe achive, wenn ich darf.

Denken Sie an das Schiff und sein umgebendes Wasser als ein Rechteck im Meer (Brett). Um alle Zellen innerhalb eines Rechtecks ​​zu überprüfen, ist es einfach, in einer verschachtelten Schleife zu arbeiten. Die Ecken des Suchrechtecks ​​richtig zu definieren, kann kniffliger sein, aber nicht zu viel.

Ich glaube, ich habe herausgefunden, wie man die Daten über die Schiffe zu speichern (die benötigten diejenigen zumindest), so dass dieser Code-Snippet funktionieren sollte:

const int rows = 10; 
const int cols = 10; 

bool CheckPlace(int row, int column, DIRECTION direct, Battleship ship) { 

    // check if the top left corner of the ship is inside the board 
    if (row < 0 || row >= rows || column < 0 || column >= cols) 
     return false; 

    int r_min = row,   // temporary top side of the rectangle 
     c_min = column,   // temporary left side 
     r_max = row + 2,  // temporary bottom side 
     c_max = column + 2;  // temporary right side 

    // update top and left size if there is enough space 
    if (r_min > 0) --r_min; 
    if (c_min > 0) --c_min; 

    // use ship length and direction to update values for right and bottom side 
    // max values are one past the border of the rectangle 
    if (horizontal == direct) 
     c_max += ship.GetLength() - 1; 
    else 
     r_max += ship.GetLength() - 1; 

    // check if the bottom rigth corner of the ship is outside the board 
    if (r_max > rows + 1 || c_max > cols + 1) 
     return false; 

    // clip the rectangle if the ship is near the border 
    if (r_max > rows) 
     --r_max; 
    if (c_max > cols) 
     --c_max; 

    // check inside the rectangle 
    for (int i = r_min; i < r_max; ++i) { 
     for (int j = c_min; j < c_max; ++j) { 
      if ('_' != board[i][j]) 
       return false; 
     } 
    } 

    // open water 
    return true; 
}