首页 > 代码库 > 编程算法基础-3.2自底向上风格

编程算法基础-3.2自底向上风格

3.2自底向上风格

自顶向下不是万能的

需求发生变化时,会很尴尬

变化是需求的本质特征

内部或外界的环境一旦发生小小的变化,就会造成很大的变动

 

个人---完全掌控-----》简单的软件逻辑《-----完全计划的模式

小组协作---掌控变化----》庞大的软件规模---产生--》自适应变化《-----解决-----主流解决方案:面向对象

面向对象正是采用自底向上的设计风格

打印控制台表格2

实际开发中,使用混合风格,根据项目的要求而定

需求:不变,变

不变---》多种风格选择---》完成任务

变化---》估算变化---》确定风格---》完成任务

 

Excel是把每一个小格子确定为一个对象,仔细的去设计这个对象应当拥有的功能和其他对象的关系

 

自底向上的分析:

想象每一个小格子画出来以后进行组合就能完成要求。

构造这样的一个小对象,把它的功能调试完备,通过组合完成需求

 

设计一个小对象

用draw方法画出一个小单元格

利用外层循环画出整个表格

/*
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                
$   $   $   $   $   $   $   $   $                
$   $   $   $   $   $   $   $   $                
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                
$   $   $   $   $   $   $   $   $                
$   $   $   $   $   $   $   $   $                
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                
$   $   $   $   $   $   $   $   $                
$   $   $   $   $   $   $   $   $                
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*/                
package topToBottom;
 
//小单元类
class Cell{
    private int x;//左上角位置
    private int y;
    private int width;
    private int height;
    //构造方法
    public Cell(int x,int y,int width,int height){
       this.x = x;
       this.y = y;
       this.width = width;
       this.height = height;
    }
    //把自己描绘到cache[][]上去,我这里写的是a[][]
    public void draw(char[][] a){
       for(int i=0;i<width;i++){//画水平线两条
           a[y][x+i] = ‘$‘;//上面
           a[y+height-1][x+i] = ‘$‘;//下面
       }
       for(int i=0;i<height;i++){//画两条竖直线
           a[y+i][x] = ‘$‘;//左边
           a[y+i][x+width-1] = ‘$‘;//右边
       }
    }
}
 
public class Print {
    public static void main(String[] args) {
       char[][] a = new char[20][50];
      
       for(int i=0;i<3;i++){//3行
           for(int j=0;j<8;j++){//8列
              Cell x = new Cell(j*4, i*3, 5, 4);
              x.draw(a);
           }
       }
       print(a);
    }
   
    //打印
    public static void print(char[][] a){
       for(int i=0;i<a.length;i++){
           for(int j=0;j<a[i].length;j++){
              if(a[i][j]==0){
                  System.out.print(" ");
              }else{
                  System.out.print(a[i][j]);
              }
           }
           System.out.println();
       }
    }
}
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                
$   $   $   $   $   $   $   $   $                
$   $   $   $   $   $   $   $   $                
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                
$   $   $   $   $   $   $   $   $                
$   $   $   $   $   $   $   $   $                
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$                
$   $   $   $   $   $   $   $   $                
$   $   $   $   $   $   $   $   $                
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       

自底向上的一个要点:在需求有变化的时候,小对象的重用能力很强。一个对象将来可以用于其他的项目

实际上具体的项目开发过程中,多种风格经常是混合着交叉使用的

 

模拟游戏

模拟井字棋游戏

九个格子中双方轮流落子。

其中一方画x符号,另一方画o符号。

开始时,9个格子都是空的。

程序显示当前局面,提示某一方输入落子位置,然后显示局面,再提示另一方。

当某方棋子连成直线,该方获胜!

例如:

初始:

_ _ _

_ _ _

_ _ _

o 输入位置: 1,1

o _ _

_ _ _

_ _ _

x 输入位置: 2,2

o _ _

_ x _

_ _ _

当某一方出现了3个棋子连成直线或对角线,则该方获胜

/*
 * 模拟井字棋游戏
九个格子中双方轮流落子。
其中一方画x符号,另一方画o符号。
开始时,9个格子都是空的。
程序显示当前局面,提示某一方输入落子位置,然后显示局面,再提示另一方。
当某方棋子连成直线,该方获胜!
例如:
初始:
_ _ _
_ _ _
_ _ _
o 输入位置: 1,1
o _ _
_ _ _
_ _ _
x 输入位置: 2,2
o _ _
_ x _
_ _ _
当某一方出现了3个棋子连成直线或对角线,则该方获胜
*/
 
package bottomToTop;
 
import java.util.Scanner;
 
public class GameJing {
    public static void main(String[] args) {
       System.out.println("初始:");
       char[][] a = init();//初始化数组,棋盘
       showMatrix(a);//展示棋盘
      
       while(true){
           turnOfO(a);
           if(judge(a)){
              System.out.println("O胜!!!");
              break;
           }
           if(peace(a)){
              System.out.println("和棋!");
              break;
           }
           turnOfX(a);
           if(judge(a)){
              System.out.println("X胜!!!");
              break;
           }
           if(peace(a)){
              System.out.println("和棋!");
              break;
           }
       }
    }
   
    //三个一样即赢
    public static boolean judge(char[][] a){
       boolean b = false;
       for(int i=0;i<3;i++){
           if(a[i][0]!=‘-‘ && a[i][0]==a[i][1] && a[i][1]==a[i][2]){//横向3个相同
              b=true;
           }
           if(a[0][i]!=‘-‘ && a[0][i]==a[1][i] && a[1][i]==a[2][i]){//纵向3个相同
              b=true;
           }
       }
       if(a[0][0]!=‘-‘ && a[0][0]==a[1][1] && a[1][1]==a[2][2]){
           b = true;
       }
       if(a[0][2]!=‘-‘ && a[0][2]==a[1][1] && a[1][1]==a[2][0]){
           b = true;
       }
       return b;
    }
   
    //和棋
    public static boolean peace(char[][] a){
       int count = 0;
       for(int i=0;i<3;i++){
           for(int j=0;j<3;j++){
              if(a[i][j]!=‘-‘){//如果没有‘-‘,表示棋盘已经被占满,没有胜负,则和棋
                  count++;
              }
           }
       }
       return count==9;
    }
   
    //O下棋
    public static void turnOfO(char [][] a){
       Scanner scan = new Scanner(System.in);
       System.out.print("O输入位置:");
       String s = scan.nextLine();
       Cell co = new CellO(s);
       if(co.wrong_input){//输入格式范围不对
           turnOfO(a);//调用自己,重新来
       }else if(a[co.x][co.y]==‘X‘||a[co.x][co.y]==‘O‘){//已经被占了
           System.out.println("该位置有棋子,请重新输入");
           turnOfO(a);//调用自己,重新来          
       }else{
           co.draw(a);//绘制下棋
           showMatrix(a);//展示棋盘结果
       }
    }
    //X下棋
    public static void turnOfX(char [][] a){
       Scanner scan = new Scanner(System.in);
       System.out.print("X输入位置:");
       String s = scan.nextLine();
       Cell cx = new CellX(s);
       if(cx.wrong_input){//输入格式范围不对,或者已经被占了
           turnOfX(a);//调用自己,重新来
       }else if(a[cx.x][cx.y]==‘X‘||a[cx.x][cx.y]==‘O‘){//已经被占了
           System.out.println("该位置有棋子,请重新输入");
           turnOfX(a);//调用自己,重新来
       }else{
           cx.draw(a);//绘制下棋
           showMatrix(a);//展示棋盘结果
       }
    }
   
    //显示二维数组
    public static void showMatrix(char[][] a){
       for(int i=0;i<3;i++){
           for(int j=0;j<3;j++){
              System.out.print(" "+a[i][j]);
           }
           System.out.println();
       }
    }
    //初始化
    public static char[][] init(){
       char[][] a =new char[3][3];
       for(int i=0;i<3;i++){
           for(int j=0;j<3;j++){
              a[i][j] = ‘-‘;
           }
       }
       return a;
    }
}
package bottomToTop;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public abstract class Cell {
    public int x;
    public int y;
    public boolean wrong_input = false;
    public Cell(String s){
       Pattern pt = Pattern.compile("([1-3]{1}),([1-3]{1})");
       Matcher m = pt.matcher(s);
       if(m.find()){
           this.x = Integer.valueOf(m.group(1))-1;
           this.y = Integer.valueOf(m.group(2))-1;
       }else{
           System.out.println("输入格式有误,请重新输入");
           wrong_input = true;
       }
    }
    public abstract void draw(char[][] a);
}
package bottomToTop;
 
public class CellO extends Cell {
 
 
    public CellO(String s) {
       super(s);
       // TODO Auto-generated constructor stub
    }
 
    @Override
    public void draw(char[][] a) {
       a[x][y]=‘O‘;
    }
}
package bottomToTop;
 
public class CellX extends Cell {
 
 
    public CellX(String s) {
       super(s);
       // TODO Auto-generated constructor stub
    }
 
    @Override
    public void draw(char[][] a) {
       a[x][y]=‘X‘;
    }
}
初始:
 - - -
 - - -
 - - -
O输入位置:1,1
 O - -
 - - -
 - - -
X输入位置:1,1
该位置有棋子,请重新输入
X输入位置:asdf
输入格式有误,请重新输入
X输入位置:1,2
 O X -
 - - -
 - - -
O输入位置:2,2
 O X -
 - O -
 - - -
X输入位置:2,3
 O X -
 - O X
 - - -
O输入位置:3,3
 O X -
 - O X
 - - O
O胜!!!

编程算法基础-3.2自底向上风格