【发布时间】:2011-03-23 14:30:10
【问题描述】:
我正在编写奥赛罗游戏,并以下列方式存储在HashMap 中找到的可能动作:
Hashmap<Matrix, PossibleMovesVector>
Matrix 是一个包含int[8][8] 的对象,它描述了当前的棋盘情况。它以下列方式覆盖hashCode() 和equals()。 (这是必要的,因为多维数组的标准 hashCode() 不查看嵌套数组的内容。)
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.deepHashCode(board);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Matrix other = (Matrix) obj;
if (!Arrays.equals(board, other.board))
return false;
return true;
}
这似乎工作正常。但是当我测试它并在我的屏幕上绘制大约 100 块左右的新板时,我的控制台中突然收到以下消息:
已识别的哈希码 xxxxxxxxxx
从 HashMap 获取动作...
但这发生在我知道是新的板子上。难道奥赛罗有这么多的状态,哈希码会重复自己吗?这是我能找到的唯一解释。那,或者我的代码有问题。但我不认为最后一种情况是这样,因为出错需要很长时间。
编辑:
这大致就是我的程序的工作方式。 getMoves() 有点罗嗦,但它所做的只是:检查棋盘是否已经检查过移动,如果没有检查可能的移动。
- 每当玩家移动时,m.board 就会改变。 (而不是制作一个全新的 Matrix 对象。)
- boardHash 包含另一个哈希表(不过我更喜欢一个简单的数组),它存储可能的移动是针对玩家 1 还是玩家 2。在我之前的帖子中,我认为这无关紧要,因此将其简化为单个向量。
代码大致如下:
public void Init(){
//Initialize board
m_board = new Matrix(new int[8][8]);
m_board.Init();
//Compute initial possible moves
boardHash.put(m_board, new HashMap<Integer, Vector<Matrix>>());
boardHash.get(m_board).put(whosTurn, getPossibleMoves(whosTurn));
}
public Vector<Matrix> getPossibleMoves(int forWho) {
// Assign variable so the code doesn't get too cluttered
HashMap<Integer, Vector<Matrix>> moveMap = boardHash.get(m_board);
// Maybe moveMap doesn't even exist is our lookup table yet
if(moveMap == null){
System.out.println("\nNever before seen board...");
moveMap = new HashMap<Integer, Vector<Matrix>>();
boardHash.put(m_board, moveMap);
moveMap.put(forWho,getPossibleMoves(forWho));
}else{
System.out.println("\nRecognized hashCode "+m_board.hashCode());
// If it does exist, maybe no possible moves are stored in it
if(moveMap.get(forWho)==null){
boardHash.put(m_board, m_board.board);
//So then make it:
// System.out.println("No moves for "+side+" yet...");
Vector<Matrix> v_possMoves = new Vector<Matrix>();
//For every empty square on the current field...
for(int column = 0; column<8; column++){
for(int row = 0; row<m_board.board[column].length; row++){
if(m_board.board[column][row] == 0){
//Check if this move is valid, and if it is, return the resulting board
Matrix possibleMoveMatrix = new Matrix(makeLines(column,row,forWho));
if(possibleMoveMatrix.board != null){
//add it to the vector
v_possMoves.add(possibleMoveMatrix);
}
}
}
}
if(v_possMoves.isEmpty()){
System.out.println("No possible moves for player "+forWho);
}
moveMap.put(forWho,v_possMoves);
}
}
return moveMap.get(forWho);
}
【问题讨论】:
-
欢迎来到 SO,Maarten!我们感谢您的礼貌,但不鼓励在本网站上进行介绍(以及在较小程度上签名)。这主要是因为它们在问题预览中占用了大量空间。此外,如果您将代码缩进四个空格,则不必同时使用反引号。抛开这些小事不谈,第一次发帖不错!
-
我不知道
Hashmap使用什么散列算法,但简单的散列容易发生冲突,小型散列表也是如此。