首先,我只是在数所有现有的世界,然后将该数字添加到
"world"
中以获得名称。但是,我担心一个极端的情况,例如有人将创造5个世界,然后删除"world4"
,然后游戏会再次建议名称"world5"
,如果玩家不注意,他们的保存将被覆盖。当用户选择开始一个新游戏时,将出现一个由正确的字符串填充的TextField,该字符串为
"world"
,后跟下一个未使用的数字。String startName = this.getFirstUnusuedWorldName(this.getNumWorlds());
this.worldNameField = new TextField(startName, this.skin);
这是
getNumWorlds()
方法:private int getNumWorlds() {
FileHandle[] files = Gdx.files.local("worlds/").list();
int numDirectories = 0;
for (FileHandle handle : files) {
if (handle.isDirectory()) {
numDirectories++;
}
}
return numDirectories;
}
这是
getFirstUnusuedWorldName
方法:private String getFirstUnusuedWorldName(int numWorlds) {
FileHandle[] files = Gdx.files.local("worlds/").list();
if (files.length == 0) {
return "world1";
}
ArrayList<String> possibleNames = new ArrayList<String>();
for (int i = 1; i <= numWorlds + 1; i++) { //world names start with 1, need to search 1 past length
possibleNames.add("world" + String.valueOf(i));
}
for (String possibleName : possibleNames) {
boolean containsName = false;
for (FileHandle file : files) {
if (file.name().equals(possibleName)) {
containsName = true;
}
}
if (!containsName) {
return possibleName;
}
}
return "world1";
}
我希望有更好的方法来做到这一点。
#1 楼
您设法做正确的事,但是您做的方式有点...我们该怎么说...?扭曲吗?向后?非最佳选择!您的方法:
获取目录中所有文件的列表
遍历一个范围并将可能的名称添加到列表中
浏览可能的名称并检查其是否与现有文件匹配
我对此的评论:
使用正确的数据结构将极大地帮助您这里。将现有文件名添加到
Set<String>
将使查找时间为\ $ O(1)\ $。完全没有必要将名称添加到列表中,因为之后您可以直接遍历该列表。
通过特定范围也是不必要的。从1开始循环,直到找到一个空闲点才停止。
这也将使不需要特殊情况的
files.length == 0
。我们可以得到以下结果:
private String getFirstUnusuedWorldName() {
FileHandle[] files = Gdx.files.local("worlds/").list();
Set<String> fileNames = new HashSet<String>();
for (FileHandle handle : files) {
fileNames.add(handle.getName());
}
for (int i = 1; ; i++) {
String name = "world" + i;
if (!fileNames.contains(name)) {
return name;
}
}
}
请注意,
for
-loop中没有停止条件(您迟早不需要一个,将有一个空白点)。还要注意,您不再需要
int numWorlds
参数。#2 楼
借助播放器@Quill进行编辑。假设播放器不在乎分配给文件的名称,那么浏览文件树并为可能的用户交互设置异常似乎是很多工作。 >
您似乎正在搜索要添加到基本世界名称的唯一字符串。一个容易以时间戳记的形式获得,例如基于基本世界名称,年,月,时,分和秒的
world20150709132530
。很抱歉,由于我不熟悉该语言,所以无法提供代码示例,但这应该可以在参考文档中轻松获得。移至其他时区,夏季时间或时钟重新同步。在所有情况下,如果用户在新时间范围内保存与前一个时间范围相同的“第二秒”,则会出现问题。使用UTC可以消除前两个错误,但是如果用户查看当前不在UTC时区的国家/地区的文件名,则会给用户增加一层困惑。
评论
\ $ \ begingroup \ $
该名称用于填充播放器可见的TextField,所以在我看来,最好不要使用奇数。有趣的方法!
\ $ \ endgroup \ $
–巴佐拉
2015年7月9日在15:14
\ $ \ begingroup \ $
world-2015-Jul-09-T13:25:30更好吗?使用例如字符串文件名= new SimpleDateFormat(“'world'-yyyy-MMM-dd-'T'HH:mm:ss”)。format(new Date());
\ $ \ endgroup \ $
– pbeentje
15年7月10日在8:04
\ $ \ begingroup \ $
@pbeentje我认为世界上没有一个允许在文件名中使用的OS。
\ $ \ endgroup \ $
–西蒙·福斯伯格
15年7月13日在16:45
\ $ \ begingroup \ $
@SimonAndréForsberg遵循“单一Unix规范”文件名规则的任何操作系统都允许使用除NUL和正斜杠之外的任何字符。其中包括OS X和Linux,分别是iOS和Android的基础。请参阅开放组基本规范。
\ $ \ endgroup \ $
–杰瓦
2015年9月2日15:03