java如何为TictaToe游戏创建HashMap
我正在创建一个Tictatcoe游戏,有两个棋盘,用户只能玩一个。如果用户单击网格1上的单元格[2][3],将在网格1和网格2上的单元格[2][3]上绘制令牌。我在考虑使用HashMap为每个单元格分配索引。与单元格[2][3]和单元格[2][3]一样,每个单元格都将被分配到索引9。我该如何实现这是我的代码?我会用Hashmap来做我想做的事情吗?我不熟悉这个概念,所以我可能只是想得太多了。 注:单元格[]是网格1的单元格,单元格[]是网格2的单元格。单元格[][]中有随机索引,因此可以将其随机分配给电路板
编辑:如果我想链接单元格(2)(3)和单元格(2)(3),我会在初始化hashmap时将整数改为单元格。然后我会做HMap。把(单元格[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 楼答案
所以本质上你想把一个网格上的一个单元格(玩家可以玩)映射到另一个网格上的某个单元格(阴影网格)
可以使用另一个2D数组来实现这一点,该数组存储单元映射到另一个网格中的索引,但需要返回一个包含x和y坐标的点对象。但这种方法有点烦人,而且有其局限性
如果你想用一个网格中的一个}并执行如下操作:
Point
的HashMap<Point, Point>
替换另一个网格中的Point
,那么你必须重写hashCode()
和equals()
{然而,如果你想有多个阴影网格,那么你需要有一个从可播放网格中的点到每个阴影网格中的点的贴图
因此,既然已经有了
Cell
类,为什么不让每个Cell
存储它映射到的所有单元格的List<Cell>
。这也是非常灵活的,因为你甚至可以将一个可播放的Cell
映射到一个阴影网格中的多个单元格,在可播放的Cell
上悬停,你可以浏览它映射到的阴影Cells
列表,并将其高亮显示阴影
Cells
不会映射到任何其他单元格,因此shadowCell.getCellThisMapsTo()
将返回null
。但这种方法可以很容易地将可播放单元映射到阴影单元并跟踪它们,甚至不需要使用HashMap
或跟踪Point
到Point
的映射以下是我对
Point
的定义。如果您想根据其值(而不是对象引用)将某个内容放入哈希映射中,那么重写hashCode()
和equals()
是很重要的: