![](/img/trans.png)
[英]I need help figuring out how to stop my program from throwing a NullPointerException
[英]Coming from C, I need some help figuring out, how to best generate Chess-Bitmaps from an input-string
我正在嘗試從象棋變體“反王象棋”的輸入字符串中生成一些位圖。 不幸的是,我必須用Java來做,但我並不十分熟悉。 到目前為止,在我寫的幾行代碼中,我已經發現,在Java和C及其派生類中,對某些事情的看法大不相同。
就像您在下面的例外中看到的那樣,我有一個構造函數,它將木板作為字符串。 我對其進行迭代,並使用相應的位圖長調用函數placePiece,以便可以正確更新它。
現在,我要問的第一個問題是 :由於您無法用Java進行“按引用調用”,因此我決定返回更新的long。 感覺很“ hacky”。 在不為每種類型的片段編寫函數的情況下,更新位圖的更好方法是什么?
第二個問題:將函數的返回值分配給變量時,Java會做什么? 是否像我對“ pieces”,“ whitePieces”和“ blackPieces”所做的那樣,像更改全局變量一樣具有運行時效率?
/*
* Parse the starting board state and build the corresponding bitmaps
*/
public Board(String[] board) {
//Go through all lines
for(int i = 0; i < board.length; i++) {
//Go through all positions
for(int j = 0; j < board[i].length(); j++) {
switch(board[i].charAt(j)) {
//Pawns
case 'P': pawns = placePiece(pawns, i, j, true); break;
case 'p': pawns = placePiece(pawns, i, j, false); break;
//Bishop
case 'B': bishops = placePiece(bishops, i, j, true); break;
case 'b': bishops = placePiece(bishops, i, j, false); break;
//Rook
case 'R': rooks = placePiece(rooks, i, j, true); break;
case 'r': rooks = placePiece(rooks, i, j, false); break;
//Knight
case 'N': knights = placePiece(knights, i, j, true); break;
case 'n': knights = placePiece(knights, i, j, false); break;
//Queen
case 'Q': queens = placePiece(queens, i, j, true); break;
case 'q': queens = placePiece(queens, i, j, false); break;
//King
case 'K': kings = placePiece(kings, i, j, true); break;
case 'k': kings = placePiece(kings, i, j, false); break;
//Anti-King
case 'A': antikings = placePiece(antikings, i, j, true); break;
case 'a': antikings = placePiece(antikings, i, j, true); break;
}
}
}
}
/*
* Function to place a Piece at the appropriate place in the bitmaps
*/
private long placePiece(long map, int row, int column, boolean white) {
//Place a 1 in the right position of the pieces long
pieces |= 1L << (row*COLUMN_NUM + column);
//Place a 1 at the right position in either the black or white pieces
if(white == true) {
whitePieces |= 1L << (row*COLUMN_NUM + column);
}else {
blackPieces |= 1L << (row*COLUMN_NUM + column);
}
//Place a 1 at the right position in the pawn long and return the changed set
return map | 1L << (row*COLUMN_NUM + column);
}
編輯:根據RaceYouAnytime的建議,將(long)1
更改為1L
。
在Java中,所有基本類型都是不可變的,因此無法更新long
。
你做的是對的。
您在問有關性能的問題,這些問題遠遠超出了典型開發人員的薪水等級。
為了對您的問題有真實的答案,應該查看編譯后生成的字節碼。
例如,您可以問自己是否將內聯placePiece
函數(這可能比更新全局變量有更大的影響)。
Java程序員對性能的關注不是很大,而不是在處理內存操作時,因為我們主要處理的是IO(DB,HTTP,Files),它們的速度要比內存慢幾個數量級。
因此,總的來說,我們嘗試優化IO,但對內存操作的關心卻少得多。
我認為您可以通過檢查方法是否內聯來節省幾微秒的時間,否則,可以使用static final
方法,該方法本質上更快。
Java中的方法都是虛擬的 ,而final
方法則不能被覆蓋。
可以使用原始類型(但編譯器通常會為您執行此操作)。
話雖這么說,關於編碼風格...您幾乎從不使用final方法,一種不使用原語的嘗試,這違背了我的性能提示,但即使您以犧牲性能為代價,也盡可能地適應Java抽象思想(在一定程度上)。
所有原始類型在Java中都有包裝器類,可用於避免您正在談論的問題
那我應該只傳遞一個元素數組嗎?
只需使用Long。 (包裝器類)
private void placePiece(Long map, int row, int column, boolean white) {
文檔可以在這里找到: https : //docs.oracle.com/javase/7/docs/api/java/lang/Long.html
請注意,如果使用“ valueOf()”方法,則實例化Long值會更有效。
https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#valueOf(long)
Long pawns = Long.valueOf(14L);
...
placePiece(pawns, i, j, true); break;
另外,由於您擔心效率,因此您可能希望堅持使用原始類型。 但是,在那種情況下,鍵入1L而不是(long)1會更有效,這樣您就不必在每次實例化時都將一種原始類型重鑄為另一種原始類型。
我在這里找到了解決我的問題的好方法: https : //chessprogramming.wikispaces.com/Bitboard+Board-Definition
基本上,您定義一個包含所有位圖的數組,然后定義常量,在給定的示例中為Enum,它在Java中不起作用,但是有定義常量的方法。 然后,您只需要傳遞常量就可以擁有數組,該數組包含全局所有位圖。
然后,您可以通過調用諸如board[PAWN]
類的名稱來調用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.