JAVA大作业3
代码
package thegreatwork;
import java.util.*;
import java.io.*;
/*Board.java
*目的:里面有一些关于如何移动、如何存储、如何生成随机数的函数
*判断游戏是否结束*/
public class Board {
//用final修饰的确定的数值,用来确定随机数的值和游戏面板尺寸大小
public final int NUM_START_TILES = 2;
public final int TWO_PROBABILITY = 90;
public final int GRID_SIZE;
private final Random random;
private int[][] grid;
private int score;
/*
*在初始化游戏面板生成随机数的构造函数
*/
public Board(int boardSize, Random random) {
this.random = random;
GRID_SIZE = boardSize;
this.score=0;
//初始化一个二维数组
this.grid=new int[boardSize][boardSize];
//让游戏面板一开始就有随机数
for(int i=0;i<NUM_START_TILES;i++){
this.addRandomTile();
}
}
/*
*获取输入面板字符串和随机值的构造函数
* 这个函数是读取之前的存档,对应gui2048里面的-i输入
*/
public Board(String inputBoard, Random random) throws IOException {
this.random = random;
Scanner input = new Scanner(new File(inputBoard));
//读取尺寸和分数
GRID_SIZE = input.nextInt();
this.score=input.nextInt();
//创建一个新的二维数组来存储这些数据
int[][] grid0=new int[GRID_SIZE][GRID_SIZE];
for(int i=0;i<grid0.length;i++){
for(int j=0;j<grid0[i].length;j++){
grid0[i][j]=input.nextInt();
}
}
//使网格对象指向新输入的数组中
this.grid=grid0;
}
/*saveBoard
*把当前游戏面板上的所有信息保存在一个文件里
*/
public void saveBoard(String outputBoard) throws IOException {
//创建流对象用于写入
PrintWriter writer=new PrintWriter(outputBoard);
//打印尺寸和分数
writer.println(GRID_SIZE);
writer.println(this.score);
//用一个循环把数据写入文件
for(int i=0;i<this.grid.length;i++){
for(int j=0;j<this.grid[i].length;j++){
writer.print(this.grid[i][j]+" ");
}
//另起一行
writer.println();
}
writer.close();
}
/*addRandomTile
*增加随机的数据来让这个游戏开始
*/
public void addRandomTile() {
//计算数值为0的框
int count=0;
for(int i=0;i<this.grid.length;i++){
for(int j=0;j<this.grid[i].length;j++){
if(this.grid[i][j]==0){
count++;
}
}
}
//如果框已满,则不增加新得随机数
if(count==0){
return;
}
//0和count-1之间取随机数
int location = this.random.nextInt(count);
//0和99之间取随机数
int value = this.random.nextInt(100);
count=0;
for(int i=0;i<this.grid.length;i++){
for(int j=0;j<this.grid[i].length;j++){
if(this.grid[i][j]==0){
count++;
//(count-1)=location的概率很小,但是如果一旦等于,就在那个位置防止随机数。
if((count-1)==location){
//如果value<90, 随机生成 2 ,不然的话随机生成 4,大部分情况下生成2.
if(value<TWO_PROBABILITY){
this.grid[i][j]=2;
}
else{
this.grid[i][j]=4;
}
}
}
}
}
}
/*rotate
*可以顺时针旋转90度或者逆时针旋转90度
*rotateClockwise是用来决定是顺时针还是逆时针,布尔型
*/
public void rotate(boolean rotateClockwise) {
//创造一个新的数组用来存储一个旋转后的游戏面板
int[][] rotate=new int[GRID_SIZE][GRID_SIZE];
//用来决定是顺时针旋转还是逆时针旋转
if(rotateClockwise){
//顺时针旋转
for(int i=0;i<this.grid.length;i++){
for(int j=0;j<this.grid[i].length;j++){
rotate[j][GRID_SIZE-i-1]=this.grid[i][j];
}
}
}
//逆时针旋转
else{
for(int i=0;i<this.grid.length;i++){
for(int j=0;j<this.grid[i].length;j++){
rotate[GRID_SIZE-j-1][i]=this.grid[i][j];
}
}
}
//旋转后的游戏面板替换掉原来的游戏面板
this.grid=rotate;
}
/*move
*根据输入的方向来移动
*/
public boolean move(Direction direction) {
if(direction.equals(Direction.UP)){
//使用Direction类的UP方法来向上移动
this.moveUp();
return this.canMoveUp();
}
if(direction.equals(Direction.DOWN)){
//使用Direction类的DOWN方法来向下移动
this.moveDown();
return this.canMoveDown();
}
if(direction.equals(Direction.LEFT)){
//使用Direction类的LEFT方法来向左移动
this.moveLeft();
return this.canMoveLeft();
}
if(direction.equals(Direction.RIGHT)){
//使用Direction类的RIGHT方法来向右移动
this.moveRight();
return this.canMoveRight();
}
return false;
}
/*isGameOver
*用来判断游戏是否已经结束了
*布尔型
*/
public boolean isGameOver() {
//当任何一种移动都可以被执行的时候就返回false也就是说游戏并不结束
if(canMoveUp())
return false;
if(canMoveDown())
return false;
if(canMoveLeft())
return false;
if(canMoveRight())
return false;
//所有可能的移动都不能执行的时候游戏就结束了
return true;
}
/*canMove
*用来判断这个移动是否可以被执行
*/
public boolean canMove(Direction direction) {
if(direction.equals(Direction.UP)){
//使用辅助的方法canMoveUp来检查是否可以执行UP
return this.canMoveUp();
}
if(direction.equals(Direction.DOWN)){
//使用辅助的方法canMoveDown来检查是否可以执行DOWN
return this.canMoveDown();
}
if(direction.equals(Direction.LEFT)){
//使用辅助的方法canMoveLeft来检查是否可以执行LEFT
return this.canMoveLeft();
}
if(direction.equals(Direction.RIGHT)){
//使用辅助的方法canMoveRight来检查是否可以执行RIGHT
return this.canMoveRight();
}
return false;
}
/*moveUp
*向上移动
*/
private void moveUp(){
for(int j=0;j<GRID_SIZE;j++){
//把所有的非0数字放到动态数组里(按列排)
ArrayList<Integer> up=new ArrayList<Integer>();
for(int i=0;i<GRID_SIZE;i++){
if(grid[i][j]!=0){
up.add(grid[i][j]);
}
}
//遍历整个列
for(int i=0;i<up.size()-1;i++){
//如果值一样的话就合并,上方变成原来的值得两倍,下方的另一个变成0
if(up.get(i).equals(up.get(i+1))){
this.score+=up.get(i)*2;
up.set(i,up.get(i)*2);
up.remove(i+1);
}
}
//把动态数组的值返回到游戏面板中
for(int i=0;i<up.size();i++){
grid[i][j]=up.get(i);
}
for(int i=up.size();i<GRID_SIZE;i++){
grid[i][j]=0;
}
}
}
/*moveDown
*向下移动
*/
private void moveDown(){
for(int j=0;j<GRID_SIZE;j++){
//把所有的非0数字放到的动态数组里(按列排)
ArrayList<Integer> down=new ArrayList<Integer>();
for(int i=GRID_SIZE-1;i>=0;i--){
if(grid[i][j]!=0){
down.add(grid[i][j]);
}
}
//遍历整个列
for(int i=0;i<down.size()-1;i++){
//add identical numbers together and remove one
if(down.get(i).equals(down.get(i+1))){
this.score+=down.get(i)*2;
down.set(i,down.get(i)*2);
down.remove(i+1);
}
}
//把动态数组的值返回到游戏面板中
for(int i=0;i<down.size();i++){
grid[GRID_SIZE-i-1][j]=down.get(i);
}
for(int i=0;i<GRID_SIZE-down.size();i++){
grid[i][j]=0;
}
}
}
/*moveLeft
*向左移动
*/
private void moveLeft(){
for(int i=0;i<GRID_SIZE;i++){
//把所有的非0数字放到的动态数组里(按行排)?
ArrayList<Integer> left=new ArrayList<Integer>();
for(int j=0;j<GRID_SIZE;j++){
if(grid[i][j]!=0){
left.add(grid[i][j]);
}
}
//遍历整个行
for(int j=0;j<left.size()-1;j++){
//add identical numbers together and remove one
if(left.get(j).equals(left.get(j+1))){
this.score+=left.get(j)*2;
left.set(j,left.get(j)*2);
left.remove(j+1);
}
}
//把动态数组的值返回到游戏面板中
for(int j=0;j<left.size();j++){
grid[i][j]=left.get(j);
}
for(int j=left.size();j<GRID_SIZE;j++){
grid[i][j]=0;
}
}
}
/*moveRight
*向右移动
*/
private void moveRight(){
for(int i=0;i<GRID_SIZE;i++){
//把所有的非0数字放到的动态数组里(按行排)?
ArrayList<Integer> right=new ArrayList<Integer>();
for(int j=GRID_SIZE-1;j>=0;j--){
if(grid[i][j]!=0){
right.add(grid[i][j]);
}
}
//遍历整个行
for(int j=0;j<right.size()-1;j++){
//add identical numbers together and remove one
if(right.get(j).equals(right.get(j+1))){
this.score+=right.get(j)*2;
right.set(j,right.get(j)*2);
right.remove(j+1);
}
}
//把动态数组的值返回到游戏面板中
for(int j=0;j<right.size();j++){
grid[i][GRID_SIZE-j-1]=right.get(j);
}
for(int j=0;j<GRID_SIZE-right.size();j++){
grid[i][j]=0;
}
}
}
/*canMoveUp
*用来判断是否可以向上移动
*/
private boolean canMoveUp(){
for(int j=0;j<GRID_SIZE;j++){
for(int i=0;i<GRID_SIZE-1;i++){
//如果在两个非0格子之间有一个0格子就返回ture
if(grid[i][j]==0){
for(int index=i+1;index<GRID_SIZE;index++){
if(grid[index][j]!=0){
return true;
}
}
}
//如果有两个相连的非0格子可以合并则返回ture
if(grid[i][j]==grid[i+1][j]&&grid[i][j]!=0){
return true;
}
}
}
return false;
}
/*canMoveDown
*用来判断是否可以向下移动
*/
private boolean canMoveDown(){
for(int j=0;j<GRID_SIZE;j++){
for(int i=GRID_SIZE-1;i>0;i--){
//如果在两个非0格子之间有一个0格子就返回ture
if(grid[i][j]==0){
for(int index=i-1;index>=0;index--){
if(grid[index][j]!=0){
return true;
}
}
}
//如果有两个相连的非0格子可以合并则返回ture
if(grid[i][j]==grid[i-1][j]&&grid[i][j]!=0){
return true;
}
}
}
return false;
}
/*canMoveLeft
*用来判断是否可以向上移动
*/
private boolean canMoveLeft(){
for(int i=0;i<GRID_SIZE;i++){
for(int j=0;j<GRID_SIZE-1;j++){
//如果在两个非0格子之间有一个0格子就返回ture
if(grid[i][j]==0){
for(int index=j+1;index<GRID_SIZE;index++){
if(grid[i][index]!=0){
return true;
}
}
}
//如果有两个相连的非0格子可以合并则返回ture
if(grid[i][j]==grid[i][j+1]&&grid[i][j]!=0){
return true;
}
}
}
return false;
}
/*canMoveRight
*用来判断是否可以向上移动
*/
private boolean canMoveRight(){
for(int i=0;i<GRID_SIZE;i++){
for(int j=GRID_SIZE-1;j>0;j--){
//如果在两个非0格子之间有一个0格子就返回ture
if(grid[i][j]==0){
for(int index=j-1;index>=0;index--){
if(grid[i][index]!=0){
return true;
}
}
}
//如果有两个相连的非0格子可以合并则返回ture
if(grid[i][j]==grid[i][j-1]&&grid[i][j]!=0){
return true;
}
}
}
return false;
}
public int[][] getGrid() {
return grid;
}
//返回分数
public int getScore() {
return score;
}
@Override
public String toString() {
StringBuilder outputString = new StringBuilder();
outputString.append(String.format("Score: %d\n", score));
for (int row = 0; row < GRID_SIZE; row++) {
for (int column = 0; column < GRID_SIZE; column++)
outputString.append(grid[row][column] == 0 ? " -" :
String.format("%5d", grid[row][column]));
outputString.append("\n");
}
return outputString.toString();
}
}