【发布时间】:2013-12-05 12:11:57
【问题描述】:
所以,这可能是也可能不是您的想法,我不完全确定我的问题措辞是否正确,但我们开始吧!我正在构建一个国际象棋游戏,并且我试图在如何调用我的类、构建棋子并将它们放在棋盘上时保持动态。
代码分析:我读了一个文件,其中包含一个片段,例如“pla1”,代表一个片段、它的颜色、它的 x 坐标和它的 y 坐标。在这个例子中,p = pawn,l = white,a = 棋盘上的 x 坐标,1 = 棋盘上的 y 坐标。所以:
“白兵在 a1 上”
简单。现在,我有一个从文件中解析棋子的棋子类,以及一个名为“Pawn”的特定类,所以当我想向棋盘添加棋子时,该棋子有自己的类来控制其移动能力和电源棋盘等等。
问题:我不知道如何动态设置我的作品类别。我可以使用硬编码版本轻松做到这一点,正如您将在 cmets 中看到的那样,或者使用 if陈述。是否可以使用我的字符串变量设置我的类?
我的代码如下:
//reads from the file, puts each line into an arraylist
public void readFromFile(String fileName) throws IOException
{
String line;
BufferedReader br = new BufferedReader(new FileReader(fileName));
//adds line to arraylist
while((line = br.readLine()) != null)
fileLines.add(line.toLowerCase());
//send each line in the list to method
for(String item : fileLines)
buildPiecesFromFileAndGetLocation(item);
}
ChessPiece[][] pieces = new ChessPiece[9][9]; my chessboard
String spawnPiece;
String spawnColor;
String pieceRepresentation;
String originx;
int originX;
int originY;
public void buildPiecesFromFileAndGetLocation(String item)
{
//regex matcher // using this to match it: Pattern copyPiece = Pattern.compile("(?<piece>q|k|b|p|n|r+)(?<color>l|d)(?<x>\\w)(?<y>\\d)");
Matcher copyMatcher = copyPiece.matcher(item);
//hashmap for matching quicker; currently only has pieceMatches.put("p", "Pawn") within it
hashIdentities();
if (copyMatcher.find())
{
spawnPiece = pieceMatches.get(copyMatcher.group("piece")); //spawnPiece becomes "Pawn"
spawnColor = colorMatches.get(copyMatcher.group("color"));
pieceRepresentation = spawnPiece + spawnColor;
originx = copyMatcher.group("x"); //change letter to number
transferChars(); //changes letter "a" into integer "1"
originY = Integer.parseInt(copyMatcher.group("y")); //string to int
//PROBLEM:
pieces[originX][originY] = new spawnPiece(pieceRepresentation); //since spawnPiece is now "Pawn" i want it to be able to call a new instance of the class Pawn. this way doesn't work. Solution?
//logic:
//pieces[a][b] = new (WHATEVER PIECE WAS MATCHED)("position + color");
//hardcoded version:
//pieces[1][1] = new Pawn("PawnWhite");
}
}
我不确定这是否可行。任何帮助将不胜感激,如果需要对代码进行任何详细说明,我可以提供。
【问题讨论】:
-
你说“硬编码”好像它是某种邪恶……而“动态地做这个或那个”就好像它是某种最佳实践。 Java 是一种静态类型语言。如果你试图设计忽略这一事实的解决方案,那么你就太努力了,你最终会得到糟糕的代码。国际象棋游戏充满了静态类型的数据(这些棋子在编译时都是已知的)。我发现您坚持必须“动态地”执行此操作(这样您就没有编译时间类型检查和安全性的优势)是荒谬的。
-
嗯,它只是我觉得很有用的东西,它是 OOP 的重要组成部分,能够动态地完成它。我宁愿以一种动态的方式来缩短我的代码。
-
那么,另一种语言会更好地满足您的需求。 Java 中的反射代码很慢。看起来和阅读起来也非常冗长和丑陋。此外,当您包含所有异常处理时,您的代码几乎总是更长、更冗长。当存在静态类型的解决方案时,避免使用 Java 中的反射代码可为您提供卓越的安全性、更高的类型安全性、卓越的健壮性和可维护性以及更高的性能。使用静态类型环境的优势非常引人注目。
-
为了更具体一点,如果您将棋子实现为
enum类(并将玩家颜色作为策略枚举——J. Bloch,Effective Java,第二版。 ) 您可以定义常量特定方法来为您提供所需的所有特定于片段的行为......同时保持静态类型解决方案的稳健性和类型安全性。 -
我明白了。在这种情况下,我只是想找到一个更动态的解决方案。谢谢