文章目录
STAGE 2
这一部分主要是依据所提供的文档然后用其中Actor、Bug以及Grid等作为基类加以扩展,主要的难度在于扩展的属性,但是很多性质都是跟文档中一些东西的性质是一样的,比如ModifiedChameleonCritter 的颜色会随着时间而变深,这个属性实际就是跟花的一样的,所以只需要将花中对应的函数复制过来即可。
##part2
对Bug类进行扩展,只需要对act以及构造函数进行重载就可以了。
CircleBug
这一个bug的特点是会转圈圈,根据题意就是每次的act中只调用一次turn函数就好了,
所以这个类中仅仅需要对act函数中的一个turn去掉就好了。
DancingBug
这一个bug的特点是根据传进来的一个5维的数组来循环进行每次的旋转角度的设定。
所以这只需要添加一个for循环并在每次读取到尾部之后再次重置为0即可
下面代码中的array是指传进来的数组
if(count == array.length)
{
count = 0;
}
for(int i = 0; i < array[count]; i++)
{
turn();
}
super.act();
count++;
SpiralBug
这一个bug的特点是在每一次转弯之后该方向的行走距离+1,所以只需要定义一个初始步长并在构造
函数中赋予初值,然后在每次turn后自加1就好,但是这时候前面的move函数就需要加一个判断条件
if (steps < sideLength && canMove())
{
move();
steps++;
}
else
{
turn();
turn();
steps = 0;
sideLength++;
}
ZBug
这一个bug的特点是在他只会进行两次转弯(如果空间足够的话),而且一开始的方向是east的,
然后接下来的方向是northweast,接着的方向又转为east,在每次需要转弯的时候直接调用
setDirection函数就好了,然后比较坑的一点是要在不能够继续行走的时候要求停下来,
这个时候就是把那个turn的那个去掉就行
if (state <= 3) //ensure it is in the side of 'Z'
{
if(steps < sideLength) {
if (canMove())
{
move();
steps++;
}
}
else if (state == 1)
{
setDirection(Location.SOUTHWEST);
steps = 0; //reset
state++; // change state
}
else if (state == 2)
{
setDirection(Location.EAST);
steps = 0; //reset
state++; //change state
}
}
part3
- 要求实现一个jumper类,主要区别在于一次性能够跳跃两个单位长
- 同时要求其他的需求自己设定,所以我的jumper是,可以吃掉bug以及flower
- 同时如果两只jumper相遇的话,其中一只是可以吃掉另外一只的
- jumper还可以翻过石头,但是如果前方是外界或者前两格是石头的话,则jumper会选择转向,而不是跳一格,可能我的jumper比较傲娇
Jumper
- 因为设定的很多东西都修改了,所以就act以及jump也都随之修改了,同时为了判断能否进行jump,还得声明一个类似canmove的函数judge_jump
- 其中judge_jump实际跟canMove函数类似,只是需要获取两格以外的location而已以及判断能否被吃掉的actor,能则为真。jump函数也是跟move类似的,只是移动的位置有一点点差别罢了。
Location loc = getLocation();
Location temp = loc.getAdjacentLocation(getDirection());
temp = temp.getAdjacentLocation(getDirection());
//获取两格以外的位置
Actor neighbor = grid.get(temp);
neighbor = grid.get(temp);
// if the location is null or flower or bug or jumper ,it can be eaten.
return (neighbor == null) || (neighbor instanceof Flower ||
neighbor instanceof Bug || neighbor instanceof Jumper);
part4
BlusterCritter
这一个Critter的特点在于根据周围25个location中critter的数目的大小来决定自己的颜色变化
如果小于预计的数目的话,就颜色变亮,反之则颜色变深
- 这一个主要的麻烦点在于获取附近的25个位置的critter的大小,然而还是需要两个for循环,虽然可能显得很low,但也没办法
for(int i = loc.getRow() - 2; i <= loc.getRow() + 2; i++ )
{
for(int j = loc.getCol() - 2; j <= loc.getCol() + 2; j++)
{
Location temp = new Location(i,j);
if(getGrid().isValid(temp))
{
Actor a = getGrid().get(temp);
if(a != null && a != this)
actors.add(a);
}
}
}
return actors;
ChameleonKid
这一个Critter的特点在于会根据前后的actor的颜色然后进行随机的选择
而没有actor在附近的时候则会跟ModifiedChameleonCritter一样颜色加深
- 这一个类直接继承ModifiedChameleonCritter就好了,然后就是getActor函数的重载就行了,因为是获取前后两个方向的Actor,所以此处就不做代码展示了。
KingCrab
这一个Critter的特点在于会将前方,左前方以及右前方位置上的其他东西给移开
移到距离自己两格以上的位置,如果没有能够一开的位置,则强行吃掉
- 这个可能是TA最喜欢检查的一个了,主要的难点在于要对对应的获取得到的Actor进行每一个的for循环,而我这里仅仅是对Actor的在kingcrab的朝向上的三个位置是否为空的一个判断,然后再做出选择。
代码如下:
private boolean move(Actor a) {
ArrayList<Location> locs = getGrid().getEmptyAdjacentLocations(a.getLocation());
for(Location loc:locs) {
int distance = (int)Math.floor(Math.sqrt(Math.pow(getLocation().getCol()
- loc.getCol(), 2) + Math.pow(getLocation().getRow()
- loc.getRow(), 2)));
if(distance > 1) {
a.moveTo(loc);
return true;
}
}
return false;
}
ModifiedChameleonCritter
这一个Critter的特点在于自己process到的列表如果是空的话,则自己颜色就会变深
这个跟花的属性是类似的,只不过多了一个arraylist的size大小的判断
- 这一个的话,就差不多是直接把flower对应的函数复制过来而已,所以就不写了
QuickCrab
这一个Critter的特点在于能够随机选择移动两格
- 这一个主要是重写一个twoway函数,主要是获取两个以外的位置,而随机选择可以直接用random函数进行判断就好了也是比较简单的。
RockHound
这一个Critter的特点在于能够将自己获取到的rock移出这个环境中,
所以也只是进行for循环判断然后调用remove函数的操作而已
- 简单的。。。。不写
Part5
part5的大部分内容是可以在文档中找到了,然后只需要对里面的几十来行代码进行修改就行了,因为里面很多没什么实际含量的代码,所以此处就不做展示了
STAGE 3
ImageProcessing
这一个主要的难点在与read函数的重写,而其他的chanel什么的只需要调用API以及套用公式就好了。所需要的知识点如下:
根据TA所给的提示:
不难知道前面给的很多信息是没用的,仅仅需要width,height以及pix(由byte转化为int类型的)。而在计算pix的过程中是需要偏移量的,因为需要补码,所以根据公式有:
//get the offset of the first address
int offset = ChangeBytesToInt(data, 10, 4);
//get the width of the picture
int width = ChangeBytesToInt(data, 18, 4);
//get the height of the picture
int height = ChangeBytesToInt(data, 22, 4);
//get the count of the bit of the picture
int bitCount = ChangeBytesToInt(data, 28, 2);
//get the size of the picture
int size = ChangeBytesToInt(data, 34, 4);
// 其中ChangeBytesToInt主要是为了将信息从byte转化为int类型的,长的如下:
// help to select the information from the byte
public int ChangeBytesToInt(byte[] data, int start, int length) {
int temp = 0;
for(int i = 0; i < length; i++)
{
temp |= ((data[start + i] & 0xff) << (i * 8));
}
return temp;
}
其他的就根据公式写吧,都长得差不多了
MazeBug
这一个难点在于要理解相应的变量是要干什么的,比如那个last我最后都没有用到,很迷,然后就是
寻找迷宫的算法了,我选择的迷宫在岔道选择的算法是概率选择法,即是概率越大的,则选择的概率
越大,不是最大选择法,emmm,总觉得概率选择比最大选择好,但是不知道是不是这样,毕竟给的
测试迷宫太小了,没办法比较,可能下一年可以让他们写一个迷宫生成算法?哈哈哈,主要的算法代码如下:
if(temp.size() == 1) {
next = temp.get(0);
probility[current.getDirectionToward(next)/90]++;
}
else {
/*
* state a sum to record the size of the valid probility and
* then choice the direction randomly
*/
float random = (float) Math.random();
float sum[] = {0, 0, 0, 0};
int sum_size = 0;
for(Location i : temp) {
int index = current.getDirectionToward(i)/90;
sum[sum_size]+=(probility[index]);
if(sum_size > 0)
sum[sum_size]+=sum[sum_size - 1];
sum_size++;
}
float choice = random * sum[sum_size-1];
for(int i = 0; i < sum_size; i++)
{
if(choice < sum[i]) {
next = temp.get(i);
probility[current.getDirectionToward(next)/90]++;
break;
}
}
}
N-Puzzle
这一道题主要是要求我们实现广搜以及启发式搜索,在网上查的话是可以找到A*算法的,启发式搜索只是其中的一种,所以根据里面的算法提示,启发式搜索主要用到的用来估计得变量是曼哈顿距离,欧拉距离的平方以及后续放错位置的个数,所以就继续用双层循环遍历吧,然后就算出随应的变量值,然后玄学调参了。。。对了,前面的广搜是可以去那个Jigsaw里面的深搜复制过来,然后换一些变量类型以及逻辑思路就好了,因为是为未知大小的,所以建议使用vector。
代码如下:
- 计算放错位置的:
for (int index = 1; index < dimension * dimension; index++) {
if (index % dimension != 0 &&
jNode.getNodesState()[index] != 0 &&
jNode.getNodesState()[index + 1] != 0 &&
jNode.getNodesState()[index] + 1 !=
jNode.getNodesState()[index + 1]) {
error_count++;
}
}
for (int index = 1; index <= dimension; index++) {
for (int j = 0; j < dimension - 1; ++j) {
if (jNode.getNodesState()[j * dimension + index] != 0 &&
jNode.getNodesState()[(j + 1) * dimension + index] != 0 &&
jNode.getNodesState()[j * dimension + index] + dimension !=
jNode.getNodesState()[(j + 1) * dimension + index]) {
error_count++;
}
}
}
计算曼哈顿距离以及欧拉距离的平方的
for (int i = 1; i <= dimension * dimension; ++i) {
if (jNode.getNodesState()[i] != 0) {
for (int j = 1; j <= dimension * dimension; ++j) {
if (jNode.getNodesState()[i] == this.endJNode.getNodesState()[j])
{
int curRow = (i - 1) / dimension;
int curCol = (i - 1) % dimension;
int endRow = (j - 1) / dimension;
int endCol = (j - 1) % dimension;
Manhattan += Math.abs(curRow - endRow) +
Math.abs(curCol - endCol);
distance += Math.pow(curRow - endRow, 2) +
Math.pow(curCol - endCol, 2);
break;
}
}
}
}
实训心得体会
这一次实训觉得可能还是搬砖会比较多一点,但是还是学习了一下java,本来一点也不会的,希望这不是今年最后一次用java,加油加油,这学期以来的爆肝都是在实训,下半学期的CPU可能会更刺激吧。哈哈哈,写了这么多,可能这一点点才算实训总结,尴尬。谢谢TA大大百忙之中看我的实训总结。
ENDENDEND
随机附一张在票圈看到的图
(然而不知道哪个**拼错了Eclipse)