大二下实训之 Java(补)

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

  1. 要求实现一个jumper类,主要区别在于一次性能够跳跃两个单位长
  2. 同时要求其他的需求自己设定,所以我的jumper是,可以吃掉bug以及flower
  3. 同时如果两只jumper相遇的话,其中一只是可以吃掉另外一只的
  4. 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)

实训总结述

猜你喜欢

转载自blog.csdn.net/qq_36347365/article/details/84931986