hooyantsing's Blog

第18次课程

字数统计: 2.9k阅读时长: 16 min
2019/05/22

源辰74班

第18次课程

05.22.2019

**内容    **

OOP

1.[项目]连连看(作业)

Class Point

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Point {
    public int x;
    public int y;
    public int data;
    public Point(int x, int y, int data) {
       super();
       this.x = x;
       this.y = y;
       this.data = data;
    }
    
    public void setData(int data) {
       this.data = data;
    }
    public boolean isSame(Point p) {
       if(this.x==p.x && this.y==p.y) {
           return true;
       }else {
           return false;
       }
    }   
    public boolean equals(Point p) {
       if(this.data==p.data) {
           return true;
       }else {
           return false;
       }
    }
}

Main Link

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import java.util.Random;
import java.util.Scanner;

public class Link {
    
    int row_len;        //行数
    int colunm_len;        //列数
    int[][] chessBoard;    //棋盘
    int pic_count = 10;    //图片数量为pic_count-1张,图片序号为1-9
    char border = 35;    //用于显示边框
    

    public static void main(String[] args) {
        Link l = new Link();
        l.showChessBoard();
        
    }

    private void showChessBoard() {
        //初始化棋盘操作
        init();
        //显示棋盘
        show();
        boolean flag = true;
        Scanner sc = new Scanner(System.in);
        do {
            System.out.println("请输入要消除的两个点的坐标(0 0 0 0):");
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();
            Point p1 = new Point(x1,y1,chessBoard[x1][y1]);
            Point p2 = new Point(x2,y2,chessBoard[x2][y2]);
            if(isEraseOK(p1,p2)==true) {
                chessBoard[p1.x][p1.y] = 0;
                chessBoard[p2.x][p2.y] = 0;
                show();
                if(isGameOver()==true) {
                    flag = false;
                }
            }    
        }while(flag);
    
    }

    //判断是否能消除
    private boolean isEraseOK(Point p1, Point p2) {

        //1.判断两个点的值是否相等
        if(p1.equals(p2)==false) {
            System.out.println(p1.data+"和"+p2.data+"两点值不同,无法消除");
            return false;
        }
        //2.判断两点是否位置一样
        if(p1.isSame(p2)) {
            System.out.println("两点坐标相同,无法消除");
            return false;
        }
        //3.判断两点的值是否为0
        if(p1.data==0 ||p2.data==0) {
            System.out.println("不能消除空对象,无法消除");
            return false;
        }
        //4.判断是否可以一线消,两线消,三线消。
        if(isOneLine(p1,p2) || isTwoLine(p1,p2) || isThreeLine(p1,p2)) {
            return true;
        }
        return false;
    }

    //三线
    private boolean isThreeLine(Point p1, Point p2) {
        Point ry = new Point(1,p1.y,chessBoard[1][p1.y]);
        Point rx = new Point(p1.x,1,chessBoard[p1.x][1]);
        for(int i=1;i<row_len-1;i++) {
            ry.x = i;
            ry.setData(chessBoard[i][p1.y]);
            if(isOneLine(p1,ry) && isTwoLine(ry,p2) && chessBoard[i][p1.y]==0) {
                return true;
            }
        }
        for(int j=1;j<colunm_len-1;j++) {
            rx.y = j;
            rx.setData(chessBoard[p1.x][j]);
            if(isOneLine(p1,rx) && isTwoLine(rx,p2) && chessBoard[p1.x][j]==0) {
                return true;
            }
        }
        return false;
    }

    //两线
    private boolean isTwoLine(Point p1, Point p2) {
        Point t1 = new Point(p1.x,p2.y,chessBoard[p1.x][p2.y]);
        Point t2 = new Point(p2.x,p1.y,chessBoard[p2.x][p1.y]);
        if(isOneLine(p1,t1) && isOneLine(p2,t1) && t1.data==0) {
            return true;
        }
        if(isOneLine(p1,t2) && isOneLine(p2,t2) && t2.data==0) {
            return true;
        }
        return false;
    }

    //一线
    private boolean isOneLine(Point p1, Point p2) {
        if(p1.x==p2.x) {
            int min = p1.y<p2.y?p1.y:p2.y;
            int max = p1.y>p2.y?p1.y:p2.y;
            for(int i=min+1;i<max;i++) {
                if(chessBoard[p1.x][i]!=0) {
                    return false;
                }
            }
            return true;
        }
        if(p1.y==p2.y) {
            int min = p1.x<p2.x?p1.x:p2.x;
            int max = p1.x>p2.x?p1.x:p2.x;
            for(int i=min+1;i<max;i++) {
                if(chessBoard[i][p1.y]!=0) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    private boolean isGameOver() {
        for(int i=1;i<chessBoard.length-1;i++) {
            for(int j=1;j<chessBoard[i].length-1;j++) {
                if(chessBoard[i][j]!=0) {
                    return false;
                }
            }
        }
        return true;
    }

    private void init() {
        Scanner sc = new Scanner(System.in);
        System.out.println("======= 难度系数控制 =======");
        System.out.println("请输入棋盘行数:");
        row_len = sc.nextInt();
        do {
            System.out.println("请输入棋盘列数(列数必须大于6列,且为偶数):");
            colunm_len = sc.nextInt();
        }while(colunm_len<6 || colunm_len%2!=0);
        
        row_len += 2;
        colunm_len += 2;
        chessBoard = new int[row_len][colunm_len];
        //上下两层边界
        for(int i=0;i<colunm_len;i++) {
            chessBoard[0][i] = border;
            chessBoard[row_len-1][i] = border;
        }
        //左右两层边界
        for(int j=0;j<row_len;j++) {
            chessBoard[j][0] = border;
            chessBoard[j][colunm_len-1] = border;
        }
        //棋盘内部生成数
        Random r = new Random();
        for(int i=1;i<row_len-1;i++) {
            for(int j=1;j<colunm_len-1;j+=2) {
                chessBoard[i][j] = r.nextInt(pic_count-1)+1;//排除0
                chessBoard[i][j+1] = chessBoard[i][j];
            }
        }
        
        for(int i=0;i<row_len*colunm_len;i++) {
            int index_x1 = 0;
            int index_x2 = 0;
            int index_y1 = 0;
            int index_y2 = 0;
            while(index_x1==0) {
                index_x1 = r.nextInt(row_len-1);
            }
            while(index_y1==0) {
                index_y1 = r.nextInt(colunm_len-1);
            }
            while(index_x2==0) {
                index_x2 = r.nextInt(row_len-1);
            }
            while(index_y2==0) {
                index_y2 = r.nextInt(colunm_len-1);
            }
            int temp;
            temp = chessBoard[index_x1][index_y1];
            chessBoard[index_x1][index_y1] = chessBoard[index_x2][index_y2];
            chessBoard[index_x2][index_y2] = temp;
        }
        
    }

    private void show() {
        System.out.println("=======当前棋盘=======");
        for(int i=0;i<colunm_len;i++) {
            System.out.print(" "+i+" ");
        }
        System.out.println();
        for(int i=0;i<row_len;i++) {
            System.out.print(i);
            for(int j=0;j<colunm_len;j++) {
                if(i==0||j==0||i==row_len-1||j==colunm_len-1) {
                    System.out.print(" "+(char)chessBoard[i][j]+" ");
                }else {
                    if(chessBoard[i][j]==0) {
                        System.out.print("   ");
                    }else {
                        System.out.print(" "+chessBoard[i][j]+" ");
                    }
                }
            }
            System.out.print(i);
            System.out.println();
        }
        for(int i=0;i<colunm_len;i++) {
            System.out.print(" "+i+" ");
        }
        System.out.println();
        
        for(int i=0;i<colunm_len;i++) {
            System.out.print("===");
        }
        System.out.println();
    }
}

2.[项目]扫雷

作者原创代码:

Class Point

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Point {
    private int x;
    private int y;
    private int state;
    //状态表示方法:0b 1111 11 1
    //前四位表示雷的数量: 8:1000 7:0111 6:0110...
    //中间两位表示当前位置打开状态: 00没开  01打开 10插旗
    //最后一位表示有无雷: 0没雷 1有雷
    public Point(int x, int y, int state) {
       super();
       this.x = x;
       this.y = y;
       this.state = state;
    }
    public Point() {
       super();
    }
    public int getX() {
       return x;
    }
    public void setX(int x) {
       this.x = x;
    }
    public int getY() {
       return y;
    }
    public void setY(int y) {
       this.y = y;
    }
    public int getState() {
       return state;
    }
    public void setState(int state) {
       this.state = state;
    }
}

Class MineMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import java.util.Random;
import java.util.Scanner;

public class MineMap {
    private int width;
    private int height;
    private int mineCount;
    //初始化棋盘
    public Point[][] getMineMap(){
        Point[][] map = new Point[height][width];
        //将Point内的State置为0
        for(int i=0;i<map.length;i++) {
            for(int j=0;j<map[i].length;j++) {
                map[i][j] = new Point(i,j,0);
            }
        }
        return burnMine(map);
    }
    
    public Point[][] burnMine(Point[][] points){
        Random r = new Random();
        for(int i=0;i<mineCount;) {//i++要判断可以加雷,才++
            int x = r.nextInt(height);
            int y = r.nextInt(width);
            //判断当前位置 points[x][y].getState() 是否有雷
            //位运算。
             /*
               1000001
              &0000001
              =0000001
             */
            if((points[x][y].getState()&0b1)!=0b1) {
                //无雷
                i++;
                /*
                 1000000
                |0000001
                =1000001
                */
                //当前位置
                points[x][y].setState(points[x][y].getState()|0b1);
                //上三个邻居
                if(x-1>=0) {
                    points[x-1][y].setState(points[x-1][y].getState()+0b1000);
                    //左上角
                    if(y-1>=0) {
                        points[x-1][y-1].setState(points[x-1][y-1].getState()+0b1000);
                    }
                    //右上角
                    if(y+1<width) {
                        points[x-1][y+1].setState(points[x-1][y+1].getState()+0b1000);
                    }
                }
                //下三个邻居
                if(x+1<height) {
                    points[x+1][y].setState(points[x+1][y].getState()+0b1000);
                    //左下角
                    if(y-1>=0) {
                        points[x+1][y-1].setState(points[x+1][y-1].getState()+0b1000);
                    }
                    //右下角
                    if(y+1<width) {
                        points[x+1][y+1].setState(points[x+1][y+1].getState()+0b1000);
                    }
                }
                //左邻居
                if(y-1>=0) {
                    points[x][y-1].setState(points[x][y-1].getState()+0b1000);
                }
                //右邻居
                if(y+1<width) {
                    points[x][y+1].setState(points[x][y+1].getState()+0b1000);
                }
                
            }else {
                //有雷
            }
        }
        return points;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    //开局 默认
    public MineMap() {
        this(10,10,30);
    }
    //自定义难度
    public MineMap(int width, int height, int mineCount) {
        super();
        this.width = width;
        this.height = height;
        this.mineCount = mineCount;
    }
    /*//选择难度 1简单/2中等/3困难
    public MineMap(int difficulty) {
        switch(difficulty) {
        case 1:
            this.width = 5;
            this.height = 5;
            this.mineCount = 10;
            break;
        case 2:
            this.width = 10;
            this.height = 10;
            this.mineCount = 30;
            break;
        case 3:
            this.width = 15;
            this.height = 15;
            this.mineCount = 50;
            break;
        case 0:
            System.out.println("请输入高,宽,雷数(空格隔开):");
            Scanner sc = new Scanner(System.in);
            this.height = sc.nextInt();
            this.width = sc.nextInt();
            this.mineCount = sc.nextInt();
            break;
        default:
            System.out.println("请重新选择");
        }
    }*/
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public int getMineCount() {
        return mineCount;
    }
    public void setMineCount(int mineCount) {
        this.mineCount = mineCount;
    }
}

Main Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
    public static void main(String[] args) {
       /*MineMap m = new MineMap();
       Point[][] map = m.getMineMap();
       Point[][] map = new  MineMap(10,10,100).getMineMap();
       for(int i=0;i<map.length;i++) {
           for(int j=0;j<map[i].length;j++)  {
               System.out.print(map[i][j].getState()+"\t");
           }
           System.out.println();
       }*/
       
       new ClearMineGame().start();
    }
}

Class ClearMineGame

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* ClearMineGame
* version:3.0
* 特性:1.增加了操作系统,包括打开和插旗操作。2.增加了放置旗子计数器。3.增加了踩到雷游戏结束。
* 4.增加了自定义模式。5.逻辑上优化,修复bug。
*
*/

import java.util.Scanner;

public class ClearMineGame {
    private MineMap map;        //地雷地图
    private int pointCount;        //旗子数
    private int useTime;        //游戏的时间
    private Point[][] minePoint;//地雷的布局
    private Scanner sc = new Scanner(System.in);
    
    
    public void start() {
        System.out.println("\t\tClearMineGame");
        int choice = 0;
        do{
            System.out.println("请选择游戏难度:");
            System.out.println("1.普通 2.中等 3.困难 0.自定义");
            choice = sc.nextInt();
            switch(choice) {
            case 1:
                map = new MineMap(5,5,9);
                //pointCount = 5*5;
                break;
            case 2:
                map = new MineMap(10,10,30);
                //pointCount = 10*10;
                break;
            case 3:
                map = new MineMap(15,15,99);
                //pointCount = 15*15;
                break;
            case 0:
                System.out.println("请输入长、宽和雷数(空格隔开):");
                int a = sc.nextInt();
                int b = sc.nextInt();
                int c = sc.nextInt();
                map = new MineMap(a,b,c);
                break;
            default:
                System.out.println("没有此选项,请重新选择!");
            }
        }while(choice>3 || choice<0);
        minePoint = map.getMineMap();
        
        while(showMineField(minePoint)) {
            optionBox(minePoint);
        }
        System.out.println();
        System.err.print("踩到雷了,游戏结束");
    }

    private void optionBox(Point[][] minePoints) {
        System.out.println("选择您的操作:1.打开 2.插旗 3.拔旗");
        int i = 0;
        i = sc.nextInt();
        switch(i) {
        case 1:
            openBox(minePoints);
            break;
        case 2:
            setFlag(minePoints);
            break;
        case 3:
            delFlag(minePoints);
        default:
                System.out.println("请重新输入");
        }
        /*if(i==1) {
            openBox(minePoints);
        }else {
            setFlag(minePoints);
        }    */
    }
    
    private void delFlag(Point[][] minePoints) {
        System.out.println("请输入打开坐标(空格隔开):");
        int x = sc.nextInt();
        int y = sc.nextInt();
        if(x<=map.getHeight() && y<=map.getWidth() && x>0 && y>0) {
            minePoints[x-1][y-1].setState(minePoints[x-1][y-1].getState() & 0b1111001);
        }else {
            System.out.println("坐标不存在,请重新输入");
        }
        
    }

    private void openBox(Point[][] minePoints) {
        System.out.println("请输入打开坐标(空格隔开):");
        int x = sc.nextInt();
        int y = sc.nextInt();
        if(x<=map.getHeight() && y<=map.getWidth() && x>0 && y>0) {
            minePoints[x-1][y-1].setState(minePoints[x-1][y-1].getState()|0b10);
        }else {
            System.out.println("坐标不存在,请重新输入");
        }
        
    }

    private void setFlag(Point[][] minePoints) {
        System.out.println("请输入插旗坐标(空格隔开):");
        int x = sc.nextInt();
        int y = sc.nextInt();
        if(x<=map.getHeight() && y<=map.getWidth() && x>0 && y>0) {
            if((minePoints[x-1][y-1].getState() & 0b110)==0b10) {
                System.out.println(x+","+y+"已经被打开,无法插旗");
            }else {
            minePoints[x-1][y-1].setState(minePoints[x-1][y-1].getState()|0b100);
            pointCount++;
            System.out.println("已经放置旗子数:"+pointCount);
            }
        }else {
            System.out.println("坐标不存在,请重新输入");
        }    
        
    }

    private boolean showMineField(Point[][] minePoints) {
        int rows = minePoints.length;
        int cols = minePoints[0].length;
        boolean flag = true;
        
        for(int i=0;i<=cols;i++) {
            if(i==0) {
                System.out.print("  \t");
            }else {
                System.out.print(i+"  ");
            }
        }
        System.out.println();
        for(int i=0;i<rows;i++) {
            System.out.print(i+1+"\t");
            for(int j=0;j<cols;j++) {
                
                //没有打开,且没有雷00x
                if((minePoints[i][j].getState() & 0b110)==0b0) {
                    System.out.print("N  ");
                }else if((minePoints[i][j].getState() & 0b110)==0b100){
                    //是否要插旗10x
                    System.out.print("F  ");
                }else {//01x
                    if((minePoints[i][j].getState() & 0b01)==0b1) {
                        //打开且是雷011
                        System.out.print("X  ");
                        flag = false;
                        //break;
                    }else {
                        //打开不是雷010
                        //System.out.print(minePoints[i][j].getState()+"\t");
                        System.out.printf("%d",minePoints[i][j].getState()>>3);
                        System.out.print("  ");
                        
                    }
                }
            }
            System.out.println();
        }
        return flag;
    }
}
CATALOG