2017-12-13 1 views
-2

2 개의 보드가있는 TicTacToe 게임을 만들면서 하나만 사용자에게 재생할 수 있습니다. 사용자가 그리드 1에서 셀 [2] [3]을 클릭하면 토큰이 그리드 1과 그리드 2의 셀 [2] [3]에 그려집니다. HashMap을 사용하여 각 셀에 인덱스를 할당 할 생각이었습니다. 셀 [2] [3] 및 셀 [2] [3]과 마찬가지로 각각 인덱스 9에 할당됩니다. 어떻게 구현합니까? 내가하려는 일에 해시 맵을 사용할 것인가? 나는이 개념에 익숙하지 않아서 나는 이것을 과소 평가할지도 모른다. 참고 : 셀 [] []은 격자 1의 셀이며 셀 [] []은 격자 2입니다. 셀 [] []은 무작위로 색인을 생성하여 보드에 임의로 할당 할 수 있습니다.TicTacToe 게임을위한 HashMap을 만드는 방법은 무엇입니까?

편집 : cell (2) (3) 및 cells (2) (3)을 링크하려면 해시 맵을 초기화 할 때 정수로 셀을 변경합니다. 그러면 HMap을 할 것입니다. put (셀 [2] [3], 셀 [2] [3]) 오른쪽?

코드 : 그래서 본질적으로 다른 그리드 (그림자 그리드)에 대한 몇 가지 셀에 하나의 그리드 (플레이어에서 재생할 수)에 셀을 매핑 할

import javax.swing.*; 
import java.awt.event.*; 
import java.awt.*; 
import javax.swing.border.LineBorder; 
import java.util.Random; 
import java.util.HashMap; 
public class Bull extends JFrame{ 
    private char currentPlayer = ' '; 
    // Creates array of cells called Cell[][] cell 
    private Cell[][] cell = new Cell[3][3]; 
    // Creates array of cells called Sale[][] cells 
    private Cells[][] cells = new Cells[3][3]; 
    // Creates a boolean array 
    private boolean t[][] = new boolean[3][3]; 
    // Creates index array 
    private int z[] = new int[8]; 
    //Initializes Random 
    Random rand = new Random(); 
    // Initializes variables which will be used to create random ints 
    int f; 
    int g; 
    // Initializes JlblStatus 
    private JLabel jlblStatus = new JLabel(" "); 
    private JLabel jlblIndex = new JLabel(" "); 
    // Method that builds the JFrame and JPanels 
    public Bull(){ 
     // Do I change Integer to array? 
     HashMap<Integer, Integer> HMap = new HashMap<Integer, Integer>(); 
     // Title of the JFrame 
     JFrame frame = new JFrame("Shadow Tic Tac Toe Game"); 
     // Makes the JFrame full screen 
     frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
     // If x button is clicked than the JFrame closes 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     // Initializes JPanel1 
     JPanel panel1 = new JPanel(); 
     // Initializes JPanel2 
     JPanel panel2 = new JPanel(); 

     // Adds panel1 which will hold the first TicTacToe game. 
     panel1.setLayout(new GridLayout(3,3,0,0)); 
     for(int d = 0; d < 3; d++){ 
     for(int c = 0; c < 3; c++){ 
      panel1.add(cell[d][c] = new Cell()); 
      // Sets size of the cells in JPanel1 
      cell[d][c].setPreferredSize(new Dimension(250,250)); 
     } 
     } 




     panel2.setLayout(new GridLayout(3,3,0,0)); 
     int n = 0; 
     while(n < 9){ 
     f=rand.nextInt(3); 
     g=rand.nextInt(3); 
     while(t[f][g] == false){ 
     t[f][g] = true; 
     panel2.add(cells[f][g] = new Cells()); 
     cells[f][g].setPreferredSize(new Dimension(250,250)); 
     System.out.println(f); 
     System.out.println("\t" + g); 
     n++; 

     } 
     } 








     // Adds Panel1 to the JFrame 
     frame.add(panel1, BorderLayout.WEST); 
     // Adds Panel2 to the JFrame 
     frame.add(panel2, BorderLayout.EAST); 
     // Updates the status of the game here (win/lose/draw/whose turn it is 
     frame.add(jlblStatus, BorderLayout.SOUTH); 
     // Sets size of the message area at the bottom of the frame 
     jlblStatus.setPreferredSize(new Dimension(100,100)); 
     // Shows the Instructions of the game 
     Instructions(); 
     // Calls method Chose() which allows the player to chose which token they will play as 
     Chose(); 
     frame.pack(); 
     // Sets it so the JFrame is visible to the user 
     frame.setVisible(true); 
    } 


    // Method that creates the Instructions for the game. Will be shown to the user prior to the user picking his token 
    public void Instructions(){ 
     JOptionPane.showMessageDialog(null,"INSTRUCTIONS" + "\nThis game is called a 'Shadow Tic Tac Toe Game'. In this game there will be two Tic Tac Toe game boards, though only one is playable. \nBut you can win on either board. Lets say you place your token on the center tile at cell(2,3). \nAn X will be drawn on that spot on board 1 and on a randomized spot on the second game board at cell(2,3). \nYou will be able to see the cell indexes before you click on a cell so you can form a strategy"); 
    } 
    // Method that lets the user chose his/her token 
    public void Chose(){ 
     int f = 2; 
     // While f == 2 the loop will run 
     while(f == 2){ 
     String input = JOptionPane.showInputDialog("CHOSE" + "\nPlease select your token. \nPress 1 for X and 2 for O."); 
     // Reads in the user input. Input put into a variable called pawn 
     int pawn = Integer.parseInt(input); 
     // If user input 1 his/her token will be X. F will equal 3 so the loop does not run again 
     if(input.equals("1")){ 
      currentPlayer = 'X'; 
      f = 3; 
     // If user input 2 his/her token will be O. F will equal 3 so the loop does not run again 
     }else if(input.equals("2")){ 
      currentPlayer = 'O'; 
      f = 3; 
     // If user does not enter in either a 1 or 2 an error message will appear. f wil equal 2 so the loop runs again and asks the user to chose his/her token again 
     }else{ 
      JOptionPane.showMessageDialog(null,"ERROR INVALID RESPONSE"); 
      f = 2; 
     } 
    } 
    } 
    public class Cells extends JPanel{ 
     private char tok = ' '; 
     public Cells(){ 
     // Sets the border for the cells to the color black 
     setBorder(new LineBorder(Color.black,1)); 
     } 
     public void setTok(char d){ 
     tok = d; 
     repaint(); 
     } 
     public char getTok(){ 
     return tok; 
     } 
     protected void Paint(Graphics g){ 
     super.paint(g); 

     if(tok == 'X'){ 
      g.drawLine(10,10,getWidth() - 10, getHeight()-10); 
      g.drawLine(getWidth()-10,10,10,getHeight()-10); 
     }else if (tok == 'O'){ 
      g.drawOval(10,10,getWidth()-20, getHeight()-20); 
     } 
     } 
    } 
    public class Cell extends JPanel{ 
     private char token = ' '; 
     public void setToken(char c){ 
     token = c; 
     repaint(); 
     } 
     public char getToken(){ 
     return token; 
     } 
     public Cell(){ 
     // Sets the border for the cells to the color black 
     setBorder(new LineBorder(Color.black, 1)); 
     addMouseListener(new MyMouseListener()); 
     } 
     protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     if (token == 'X') { 
      g.drawLine(10,10, getWidth() - 10, getHeight() - 10); 
      g.drawLine(getWidth() - 10,10,10, getHeight() - 10); 
     } 
     else if (token == 'O') { 
      g.drawOval(10, 10, getWidth() - 20, getHeight() - 20); 
     } 
     } 
     private class MyMouseListener extends MouseAdapter{ 
     public void mouseClicked(MouseEvent e){ 
     // If cell is empty and game is not over 
     if (token == ' ' && currentPlayer != ' ') { 
      setToken(currentPlayer); // Set token in the cell 
      for(int d = 0; d < 3; d++){ 
      for(int c = 0; c < 3; c++){ 
       if(cell[d][c].getToken() == 'X'){ 
        cells[d][c].setTok('X'); 
       }else if(cell[d][c].getToken() == 'O'){ 
        cells[d][c].setTok('O'); 
       }else if(cell[d][c].getToken() == ' '){ 
        cells[d][c].setTok(' '); 
       } 
      } 
      } 
      //setTok(currentPlayer); 
       if(Won(currentPlayer)){ 
        jlblStatus.setText("The game is over! " + currentPlayer + " won the game! Congragulations " + currentPlayer + " !"); 
        currentPlayer = ' '; 
       }else if(Full()){ 
        jlblStatus.setText("The game is over, it ends in a draw!"); 
        currentPlayer = ' '; 
       }else{ 
        if(currentPlayer == 'X'){ 
        currentPlayer = 'O'; 
        }else{ 
        currentPlayer = 'X'; 
        } 

        jlblStatus.setText("It is " + currentPlayer + " 's turn"); 
       } 

      } 
     } 
     } 
    } 

    public boolean Full(){ 
     for(int d = 0; d < 3; d++) 
     for(int c = 0; c < 3; c++) 
      if(cell[d][c].getToken() == ' ') 
       return false; 
      return true; 

    } 

    public boolean Won(char token){ 
     for(int d = 0; d < 3; d++){ 
     if(cell[d][0].getToken() == token && cell[d][1].getToken() == token && cell[d][2].getToken() == token){ 
      return true; 
     } 
     } 
     for(int c = 0; c < 3; c++){ 
     if(cell[0][c].getToken() == token && cell[1][c].getToken() == token && cell[2][c].getToken() == token){ 
      return true; 
     } 
     } 
     if(cell[0][0].getToken() == token && cell[1][1].getToken() == token && cell[2][2].getToken() == token){ 
     return true; 
     } 
     if(cell[0][2].getToken() == token && cell[1][1].getToken() == token && cell[2][0].getToken() == token){ 
     return true; 
     } 
     return false; 
    } 
    public static void main(String [] args){ 
     new Bull(); 
    } 
} 
+1

'새의 HashMap <>()' –

답변

0

?

다른 격자에서 셀이 매핑하는 인덱스를 저장하는 다른 2D 배열을 사용하여이 작업을 수행 할 수 있지만 x 및 y 좌표가 포함 된 점 객체를 반환해야합니다. 그러나 그 방법은 추적하기가 짜증나게하며 한계가 있습니다.

HashMap<Point, Point> mapPointToPoint = new HashMap<>(); 

// (0,0) maps to shadow grid (1,2) 
mapPointToPoint.put(new Point(0,0), new Point(1,2)); 
mapPointToPoint.put(new Point(0,1), new Point(2,1)); 
// ... more mappings for all the cells 

// to get 
Point pointInPlayableGrid = new Point(0,0); 
Point pointInShadowGrid = mapPointToPoint.get(pointInPlayableGrid); 
// pointInShadowGrid == (1,2) since that's what it was mapped to 

: 다른 그리드에서 Point 하나의 그리드에 HashMap<Point, Point>Point 한을 함께하고 싶어

, 당신은 hashCode()Pointequals()을 무시하고 같이해야 할 것이다 그러나 여러 섀도우 그리드가 필요하다면 재생 가능한 그리드의 점에서 각 섀도우 그리드의 섀도우 그리드에있는 점까지의 맵을 가져야합니다.

그렇기 때문에 이미 Cell 클래스가 있으므로 Cell에 매핑 할 모든 셀을 List<Cell>으로 저장하는 것이 좋습니다. 하나의 쉐도우 그리드에서 하나의 재생 가능한 Cell을 여러 셀에 맵핑 할 수 있고 재생 가능한 Cell의 커서를 놓으면 그림자 목록 인 Cells을 탐색하고 강조 표시 할 수도 있기 때문에 매우 유연합니다.

public class Cell extends JPanel{ 
    private Cell shadowCell; 
    public void setCellThisMapsTo(Cell otherCell){ this.shadowCell = otherCell; } 
    public Cell getCellThisMapsTo(){ return shadowCell; } 
    // ... all the other stuff 
} 

// ... wherever you initialize the playable and shadow grid 
// get a list of the shadow Cells, randomized order 
Cell[][] shadowGrid; // however you init this 
Cell[][] playableGrid; // however you init this 

LinkedList<Cell> shadowCells = new LinkedList<>(); 
for(int x = 0; x < 3; x++){ 
    for(int y = 0; y < 3; y++){ 
     shadowCells.add(shadowGrid[x][y]); 
    } 
} 
Collections.shuffle(shadowCells); 

for(int x = 0; x < 3; x++){ 
    for(int y = 0; y < 3; y++){ 
     Cell playableCell = playableGrid[x][y]; 
     Cell shadowCell = shadowCells.removeFirst(); 
     playableCell.setCellThisMapsTo(shadowCell); 
    } 
} 

// Now all the playable cells map to a random shadow cell 
Cell playableCell = playableGrid[0][0]; 
Cell shadowCell = playableCell.getCellThisMapsTo(); 

Cells 다른 세포에 매핑되지 않습니다 그림자, 그래서 shadowCell.getCellThisMapsTo()null을 반환합니다. 그러나이 방법을 사용하면 HashMap을 사용하지 않고도 재생 가능한 셀을 섀도우 셀에 쉽게 매핑하고 추적 할 수 있으며 Point의 매핑을 Point으로 추적하지 않아도됩니다.


여기 내 정의는 Point입니다. 당신이 그 값에 (오히려 그 객체 참조보다) 기반의 해시 맵에 뭔가를 넣고 싶은 경우에,이 hashCode()equals()을 무시하는 것이 중요하다 :

class Point { 
    public final int x; 
    public final int y; 
    public Point(int x, int y){ 
     this.x = x; 
     this.y = y; 
    } 

    // !!! OVERRIDE hashCode() and equals() so you can use this properly in a HashMap !!! 
    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 71 * hash + this.x; 
     hash = 71 * hash + this.y; 
     return hash; 
    } 

    @Override 
    public int equals(Object o) { 
     if (obj == null) 
      return false; 
     if (this == obj) 
      return true; 
     if (getClass() != o.getClass()) 
      return false; 
     Point p = (Point) o; 
     return this.x == p.x && this.y == p.y; 
    } 
} 
+0

그래서 컬렉션. shuffle (shadowCells)은 셀을 섞어서 섀도우 그리드의 임의의 지점에 있도록합니다. 그래서 Colelctions.shuffle을 사용할 수있는 임의의 int를 사용할 필요가 없습니다. 맞습니까? – fzk

+0

@fzk 그래, 그것은 당신을 위해 그림자 세포의 목록을 뒤섞을 것이다. 재생할 수있는 셀에는 연결되는 그림자 셀에 대한 참조가 있습니다. 이것이 귀하의 질문에 대답한다면 동의하십시오. – xtratic

관련 문제