Текст на основе 2D тральщик


У меня 1 мерная программа просто отлично, поэтому я подумал, что мне просто нужно несколько Щипков, чтобы сделать в 2D так же хорошо работать. Это не полностью завершена, но было бы полезно знать, если я на правильном пути или полностью с, где я нахожусь.

import java.util.Scanner;
import java.util.Random;

public class MS2D 
{
    public static int[][] map = new int[10][10];    // mine field is 10 cells

    public static boolean[][] played = new boolean[10][10]; // played moves

    public static int row_pick;               // row picked to play          
    public static int col_pick;               // column picked to play

    public static int threshold = 6;          // low threshold = more mines

      public static void main(String[] args) 
      {
         int r, c;                               // each 'row' & 'column' in 2-D array
         Scanner kb = new Scanner(System.in);    // keyboard input
         boolean hit, done;

         InitMap();          // get the map randomized
         ShowMap();          // show current map (all hidden)

         while( true ) // play loop starts
         {
            System.out.print("Which row and column to play? ( -1 to quit) ");
            row_pick = kb.nextInt();
            col_pick = kb.nextInt();
            if ((col_pick < 0) || (col_pick > map.length - 1) || (row_pick < 0) 
                || (row_pick > map.length - 1) )
            {
               System.out.println("Thanks for playing!");
               System.exit(0);
            }
            else 
            {
               if (played[row_pick][col_pick])
               {
                  System.out.println("That position has been played!");
                  continue;
               }    


            }   
            hit = false;
            done = false;
            if (map[row_pick][col_pick] == 9)
            {
               hit = true;
            }
            else
            {
               MarkPlayed(row_pick, col_pick);
               done = true;

               for (r = 0; r <= played.length - 1; r++) 
               {
                  for (c = 0; c <=played.length - 1; c++)
                  { 
                     if( played[r][c] == false)
                        done = false;
                  }
               }    
            }
            if (hit || done)
            {
               for(r = 0; r <= played.length - 1; r++)
               {
                  for(c = 0; c <= played.length - 1; c++)
                  {
                     played[r][c] = true;
                  }
               }
            }

            ShowMap();

            if (hit == true)
            {
               System.out.println("Boom! Bye, bye.");
               break;
            }   
            else if (done == true)
            {   
               System.out.println("Good Game!");
               break;      
            }  
         }
      }     
      public static int CountMines( int r, int c ) 
      {
         int count = 0; 
         if (c - 1 >= 0 && c - 1 == 9)
         {
            count++;
         }
         if (map[c + 1] == 9)
         {
            count++;
         }
         return count;

      } // end CountMines()

      public static void InitMap () 
      { // randomize map
         int r, c, num;
         Random rand_obj= new Random();// use Random class to create a rand_obj
         for (r = 0; r < map.length - 1; r++)
         {
            for (c = 0; c < map.length - 1; c++)
            {  
               num = rand_obj.nextInt(10);

               if (num > threshold)
               {
                  map[r][c] = 9;
               }
               else
               {
                  map[r][c] = 0;
               }
            }
         }
         for (r = 0; r < map.length - 1; r++)
         {
            for(c = 0; c < map.length - 1; c++)
            {
               if (map[r][c] == 0)
                  CountMines( r, c);   
            }
         }
      } // end InitMap()

      public static void MarkPlayed(int r, int c ) 
      {
         played[r][c] = true;

         if (r - 1 >= 0 && r - 1 != 9)  it true
         {
            if(c - 1 >= 0 && c - 1 != 9)
            {
               played[r][c] = true;
            }
            if (r + 1 >= 0 && r + 1 != 9)
            {
               if(c + 1 >= 0 && c + 1 != 9)
               {
                  played[r][c] = true;  
               }
            }
         }      
      } // end MarkPlayed()


      public static void ShowMap() 
      {
         int r, c;

         for ( r = 0; r < played.length; r++ )
         {
            for ( c = 0; c < played.length; c++ )
            {
               if ( played[r][c] ) // can show
               {
                  System.out.print( map[r][c] + " " );
               }    
               else 
               {
                  System.out.print(". "); // hidden
               }
            }
         }
         System.out.println();

         for ( c = 0; c < played.length; c++ )
         {  
            System.out.print(c + " ");
         }  
         System.out.println();

      } // end ShowMap ()
} // end class


6569
2
задан 11 декабря 2011 в 02:12 Источник Поделиться
Комментарии
1 ответ


  • Это решение не очень объектно-ориентированный. Что может быть хорошо, если вы новичок, но если вы знаете, как инициализировать объекты, вы должны использовать эти знания.

  • Имена методов должны быть в нижнем регистре

  • случайный объект должен быть повторно использованы, сделать его статическим членом

  • не пишите инт Р, С; в начале метода, просто инициализировать переменные в цикле: для(тип int с=...

  • научитесь использовать тернарный оператор, например, карты[р][с] = (числ > порог) ? 9 : 0;

И последнее, но не менее распространенная фишка для настольных игр: окружите вашу доску с невидимой границе одно поле (например, поле 10х10 станут внутренне 12х12), которые являются пустыми. Не показывайте их, не позволяют пользователю получить доступ к их. Затем, если вы установите рядом с полем для шахт, вы не должны проверить, если вы закрыты, потому что у вас есть то, что граница безопасности, и потому, что эти поля всегда пустые, ваш граф по-прежнему верны.

В качестве отправной точки, вот как я бы запустить (без взаимодействия с пользователем или игровой цикл, но с расчет и отображение сделано):

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class MS2D {

private static class Field {

public boolean hidden = true;
public final boolean mine;
public int neigbors = 0;

public Field(boolean mine) {
this.mine = mine;
}
}
private final int size;
private Field[][] board;

private MS2D(int size, int numberOfMines) {
this.size = size;
initBord(numberOfMines);
calculateNeighbors();
showBoard();
}

private void initBord(int numberOfMines) {
List<Field> mines = new ArrayList<Field>();
for (int i = 0; i < size * size; i++) {
mines.add(new Field(i < numberOfMines));
}
Collections.shuffle(mines);
board = new Field[size + 2][size + 2];
for (int i = 0; i < size + 2; i++) {
for (int j = 0; j < size + 2; j++) {
board[i][j] = (i == 0 || j == 0 || i == size + 1 || j == size + 1)
? new Field(false)
: mines.remove(0);
}
}
}

private void calculateNeighbors() {
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= size; j++) {
int count = 0;
for (int di = -1; di <= 1; di++) {
for (int dj = -1; dj <= 1; dj++) {
if (board[i + di][j + dj].mine) count++;
}
}
board[i][j].neigbors = count;
}
}
}

private void showBoard() {
for(int i = 1; i <= size; i++) {
System.out.printf("%2d| ",i);
for(int j = 1; j <= size; j++) {
Field f = board[i][j];
if(f.hidden) {
System.out.print(". ");
} else if (f.mine) {
System.out.print("* ");
} else {
System.out.print(f.neigbors + " ");
}
}
System.out.println();
}
System.out.print(" ");
for(int i = 1; i <= size; i++) {
System.out.print(i / 10 + " ");
}
System.out.print("\n ");
for(int i = 1; i <= size; i++) {
System.out.print(i % 10 + " ");
}
System.out.println();
}

public static void main(String[] args) {
new MS2D(15, 15);
}
}

Обратите внимание, что в реальных приложениях этот подход до сих пор не "ОО" достаточно, так как существует тесная взаимосвязь между моделью и пользовательским интерфейсом. В идеале вы должны вынести все взаимодействие пользователей в отдельный класс, который упростит позже рефакторинга (например, с помощью качания вместо консоли). Тем не менее, я чувствовал, что за это маленький пример, это будет, наверное, перебор.

3
ответ дан 12 декабря 2011 в 02:12 Источник Поделиться